Library ExtGraph  -  Documentation

Version 2.00

Extended Graphic Routines for TIGCC Projects

Release Date: 25/12/2004 (Beta 4)



PREFACE:

The ExtGraph Library is an add-on to the TIGCC Library (TIGCCLIB). Integrating ExtGraph into TIGCCLIB is planned, although it is unlikely that this ever happens.. It's a compile-time library (used functions are fetched from the library during the linking stage) and it contains various useful graphics related routines which are missing in the TIGCCLIB or modified routines which are implemented with very high speed in mind (without stupid excessive speed optimizations, though, except for preshifted sprites which are a brute force approach). For example, we unrolled tight loops in the tilemap engine, which costed around 12 bytes (< 1/1000 of overall size for most programs using a tilemap engine), but increases speed by ~20%.
Note: We do not / cannot guarantee that any other compiler or cross-compiler for TI-68k calculators than TIGCC will support ExtGraph.

The ExtGraph demos were tested on PedroM 0.80. PedroM exits demo12 and demo17 because ROM_CALL CharNumber (not currently documented in TIGCC, but it is in my fastitoa.h package) is not reimplemented, but all other demos work (although PedroM 0.80 seems to suffer more from the keyboard rebounds, tested on VTI) and show that PedroM uses more efficient algorithms than AMS (in graphical functions - vital memcpy and memset are very slow in PedroM versions to date): ExtGraph outperforms PedroM on lines by <~10% and rectangles by >~3x, while it usually outperforms AMS by >~5x on lines and >~7x on rectangles.


The ExtGraph 2 series is supposed to be backwards compatible with the previous versions, except:

If you find something else that won't compile (especially the optimized pixel macros - we've already been reported bugs at least twice), please report it to us !




ABOUT THE GRAYSCALE MONSTER FUNCTIONS:

The GraySprite routines are real "monsters" due to their number of parameters. I've never planned to implement them this way, but there were too many requests. Reducing a bit the number of parameters is planned for special GrayClipSprite16x16 (most used sprite format), by switching to a special sprite format, but we will NOT combine the consecutive planes into one double-sized plane. Indeed, the latter a) doesn't have any significant advantage speed-wise or size-wise compared to the normal method and b) it forbids writing directly to the grayscale outputscreen or using doublebuffering, because the buffers used by the TIGCCLIB grayscale routine are not combined this way on HW1. Therefore I've decided to implement these "monsters".
GrayClipISprite8/16_... are highly speed-optimized by using interlaced sprites and two different loops to optimize shiftings.
A number of programs (sidescroller Venus is one of them) contain routines whose prototype is similar to that of GrayClipISprite routines (single pointer to a sprite), but the sprite format is different: it contains the entire data for one plane, the entire data for the other plane, the entire mask data if any (or any permutation of these three blocks). Using this format is nearly as efficient speed-wise and speed-wise as using interlaced sprites. Starting from Beta 4, you can find information in the readme, so that all users (even those who don't know ASM, what a shame) can modify them to use this format without too much trouble.


WHY EXTGRAPH 2.xx VERSIONS ARE A GREAT IMPROVEMENT OVER 1.xx AND OLDER:


This is a beta, this means it may contain bugs we might not have seen despite our tests (Beta 4 needed the entire library to be more or less retested, see the changelog). We already saw several more or less severe bugs in Beta 0, 1, 2, 3.




As of Beta 4, the tilemap engine is still incompatible with the TIGCCLIB grayscale doublebuffering support.


Contents


Functions, Types, Globals and Macros

Library ExtGraph contains the following functions:

Sprite8_AND                  Sprite16_AND                  Sprite32_AND                   SpriteX8_AND
Sprite8_AND_R                Sprite16_AND_R                Sprite32_AND_R                 SpriteX8_AND_R
GraySprite8_AND              GraySprite16_AND              GraySprite32_AND               GraySpriteX8_AND
GraySprite8_AND_R            GraySprite16_AND_R            GraySprite32_AND_R
ClipSprite8_AND_R            ClipSprite16_AND_R            ClipSprite32_AND_R
GrayClipSprite8_AND_R        GrayClipSprite16_AND_R        GrayClipSprite32_AND_R

Sprite8_BLIT                 Sprite16_BLIT                 Sprite32_BLIT                  SpriteX8_BLIT
Sprite8_BLIT_R               Sprite16_BLIT_R               Sprite32_BLIT_R                SpriteX8_BLIT_R
GraySprite8_BLIT             GraySprite16_BLIT             GraySprite32_BLIT              GraySpriteX8_BLIT
GraySprite8_BLIT_R           GraySprite16_BLIT_R           GraySprite32_BLIT_R
ClipSprite8_BLIT_R           ClipSprite16_BLIT_R           ClipSprite32_BLIT_R
GrayClipSprite8_BLIT_R       GrayClipSprite16_BLIT         GrayClipSprite32_BLIT_R

Sprite8Get                   Sprite16Get                   Sprite32Get                    SpriteX8Get
Sprite8Get_R                 Sprite16Get_R                 Sprite32Get_R                  SpriteX8Get_R

Sprite8_MASK                 Sprite16_MASK                 Sprite32_MASK                  SpriteX8_MASK
Sprite8_MASK_R               Sprite16_MASK_R               Sprite32_MASK_R                SpriteX8_MASK_R
GraySprite8_MASK             GraySprite16_MASK             GraySprite32_MASK              GraySpriteX8_MASK
GraySprite8_MASK_R           GraySprite16_MASK_R           GraySprite32_MASK_R
ClipSprite8_MASK_R           ClipSprite16_MASK_R           ClipSprite32_MASK_R
GrayClipSprite8_MASK_R       GrayClipSprite16_MASK_R       GrayClipSprite32_MASK_R

Sprite8_OR                   Sprite16_OR                   Sprite32_OR                    SpriteX8_OR
Sprite8_OR_R                 Sprite16_OR_R                 Sprite32_OR_R                  SpriteX8_OR_R
GraySprite8_OR               GraySprite16_OR               GraySprite32_OR                GraySpriteX8_OR
GraySprite8_OR_R             GraySprite16_OR_R             GraySprite32_OR_R
ClipSprite8_OR_R             ClipSprite16_OR_R             ClipSprite32_OR_R
GrayClipSprite8_OR_R         GrayClipSprite16_OR_R         GrayClipSprite32_OR_R

Sprite8_XOR                  Sprite16_XOR                  Sprite32_XOR                   SpriteX8_XOR
Sprite8_XOR_R                Sprite16_XOR_R                Sprite32_XOR_R                 SpriteX8_XOR_R
GraySprite8_XOR              GraySprite16_XOR              GraySprite32_XOR               GraySpriteX8_XOR
GraySprite8_XOR_R            GraySprite16_XOR_R            GraySprite32_XOR_R
ClipSprite8_XOR_R            ClipSprite16_XOR_R            ClipSprite32_XOR_R
GrayClipSprite8_XOR_R        GrayClipSprite16_XOR_R        GrayClipSprite32_XOR_R

GraySprite8_TRANB_R          GraySprite16_TRANB_R          GraySprite32_TRANB_R
GrayClipSprite8_TRANB_R      GrayClipSprite16_TRANB_R      GrayClipSprite32_TRANB_R

GraySprite8_TRANW_R          GraySprite16_TRANW_R          GraySprite32_TRANW_R
GrayClipSprite8_TRANW_R      GrayClipSprite16_TRANW_R      GrayClipSprite32_TRANW_R


SpriteX8_MIRROR_H            SpriteX8_MIRROR_V
SpriteX8_MIRROR_H_R          SpriteX8_MIRROR_V_R
SpriteX8_MIRROR_HV_R
SpriteX8_ROTATE_RIGHT_R      SpriteX8_ROTATE_LEFT_R
SpriteX8_RR_MH_R             SpriteX8_RL_MH_R


ScaleSprite8_AND             ScaleSprite16_AND             ScaleSprite32_AND              ScaleSprite64_AND
ScaleSprite8_OR              ScaleSprite16_OR              ScaleSprite32_OR               ScaleSprite64_OR
ScaleSprite8_XOR             ScaleSprite16_XOR             ScaleSprite32_XOR              ScaleSprite64_XOR


ScrollLeft160                ScrollLeft160_R               ScrollLeft240                  ScrollLeft240_R
ScrollRight160               ScrollRight160_R              ScrollRight240                 ScrollRight240_R
ScrollUp160                  ScrollUp160_R                 ScrollUp240                    ScrollUp240_R
ScrollDown160                ScrollDown160_R               ScrollDown240                  ScrollDown240_R


FastCopyScreen               FastCopyScreen_R


FastDrawLine                 FastDrawLine_R
FastDrawHLine                FastDrawHLine_R
FastDrawVLine                FastDrawVLine_R
FastLine_Draw_R              FastLine_Erase_R              FastLine_Invert_R


FastFillRect                 FastFillRect_R
FastFilledRect_Draw_R        FastFilledRect_Erase_R        FastFilledRect_Invert_R
FastOutlineRect              FastOutlineRect_R             GrayFastOutlineRect_R
FastEraseRect160_R           FastEraseRect240_R
GrayFastEraseRect2B160_R     GrayFastEraseRect2B240_R
FastFillRect160_R            FastFillRect240_R
GrayFastFillRect2B160_R      GrayFastFillRect2B240_R
FastInvertRect160_R          FastInvertRect240_R
GrayFastInvertRect2B160_R    GrayFastInvertRect2B240_R
FastEraseRectX8_R            FastFillRectX8_R              FastEraseRectX8_R


ClearGrayScreen              ClearGrayScreen2B             GrayClearScreen                GrayClearScreen2B
ClearGrayScreen_R            ClearGrayScreen2B_R           GrayClearScreen_R              GrayClearScreen2B_R
DrawGrayRect                 DrawGrayRect2B                GrayDrawRect                   GrayDrawRect2B
InvertGrayRect               InvertGrayRect2B              GrayInvertRect                 GrayInvertRect2B
DrawGrayLine                 DrawGrayLine2B                GrayDrawLine                   GrayDrawLine2B
FastDrawGrayLine             FastDrawGrayLine2B            GrayFastDrawLine               GrayFastDrawLine2B
FastDrawGrayHLine            FastDrawGrayHLine2B           GrayFastDrawHLine              GrayFastDrawHLine2B
DrawGrayChar                 DrawGrayChar2B                GrayDrawChar                   GrayDrawChar2B
DrawGrayStr                  DrawGrayStr2B                 GrayDrawStr                    GrayDrawStr2B
DrawGrayStrExt               DrawGrayStrExt2B              GrayDrawStrExt                 GrayDrawStrExt2B


PreshiftSprite16x16          PreshiftGrayISprite16x16


FadeOutToBlack_CWS1_R        FadeOutToWhite_CWS1_R
FadeOutToBlack_CCWS1_R       FadeOutToWhite_CCWS1_R
FadeOutToBlack_LR_R          FadeOutToWhite_LR_R
FadeOutToBlack_LR18_R        FadeOutToWhite_LR18_R
FadeOutToBlack_LR28_R        FadeOutToWhite_LR28_R
FadeOutToBlack_RL_R          FadeOutToWhite_RL_R
FadeOutToBlack_RL18_R        FadeOutToWhite_RL18_R
FadeOutToBlack_RL28_R        FadeOutToWhite_RL28_R
FadeOutToBlack_TB_R          FadeOutToWhite_TB_R
FadeOutToBlack_BT_R          FadeOutToWhite_BT_R
GrayIShadowPlanesX16_R       GrayShadowPlanesX16_R
GrayIShadowPlanes160_R       GrayShadowPlanes160_R
GrayIShadowPlanes240_R       GrayShadowPlanes240_R
GrayIShadowPlanesTo_R        GrayShadowPlanesTo_R


FloodFill                    FloodFill_R
FloodFillMF                  FloodFillMF_R


UnpackBuffer (or) ttunpack_decompress and ttunpack_decompress_gray


TestCollide8                 TestCollide8_R
TestCollide16                TestCollide16_R


the following predefined types:
GrayColors
FillAttrs
ExtAttrs
TTUNPACK_HEADER
TTARCHIVE_HEADER
TTARCHIVE_ENTRY

the following global variables:
EXTGRAPH_VERSION_STR
EXTGRAPH_VERSION_PWDSTR
EXTGRAPH_VERSION_MAIN
EXTGRAPH_VERSION_SUB
and the following macros/definitions:
EXT_PIXOFFSET
EXT_PIXADDR
EXT_PIXMASK
EXT_PIXNBIT
EXT_PIXUP
EXT_PIXDOWN
EXT_PIXLEFT_AM
EXT_PIXRIGHT_AM
EXT_SETPIX_AM
EXT_CLRPIX_AM
EXT_XORPIX_AM
EXT_GETPIX_AM
EXT_SETPIX_AN
EXT_CLRPIX_AN
EXT_XORPIX_AN
EXT_GETPIX_AN
EXT_SETPIX
EXT_CLRPIX
EXT_XORPIX
EXT_GETPIX

EXT_SHORTABS
EXT_LONGABS
EXT_XCHG
EXT_LONGSWAP

ttarchive_valid
ttarchive_entries
ttarchive_desc
ttarchive_data
ttarchive_size
ttarchive_info

ttunpack_size
ttunpack_valid

TTUNPACK_OKAY
TTUNPACK_NOESCFOUND
TTUNPACK_ESCBITS
TTUNPACK_MAXGAMMA
TTUNPACK_EXTRALZP
TTUNPACK_NOMAGIC
TTUNPACK_OUTBUFOVERRUN
TTUNPACK_LZPOSUNDERRUN

BOUNDS_COLLIDE
BOUNDS_COLLIDE8
BOUNDS_COLLIDE16
BOUNDS_COLLIDE32

PSprite16x16_OR_R           GrayPSprite16x16_OR_R
PSprite16x16_XOR_R          GrayPSprite16x16_XOR_R



How to use the ExtGraph Library?



[Information valid until ExtGraph becomes part of the TIGCCLIB] [Information valid for all distributions]

Copy files extgraph.a and extgraph.h (tilemap.a and tilemap.h if you use the tilemap engine, preshift.h if you use preshifted sprites) into the directory where the rest of your sources are. To use extgraph functions now in your project add the following line:

#include "extgraph.h"
to your sourcecode.


If you are using the commandline compile your project (in this case myprog) this way:
tigcc myprog.c extgraph.a
If you are using the IDE add extgraph.a to the archive file folder of your project. That's all.

  

Fast Sprite Drawing Routines



void Sprite8_AND(short x,short y,short h,unsigned char *sprt,void *dest) __attribute__((__stkparm__));

void Sprite8_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite16_AND(short x,short y,short h,unsigned short *sprt,void *dest) __attribute__((__stkparm__));

void Sprite16_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite32_AND(short x,short y,short h,unsigned long *sprt,void *dest) __attribute__((__stkparm__));

void Sprite32_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void SpriteX8_AND(short x,short y,short h,unsigned char *sprt,short w,void *dest) __attribute__((__stkparm__));

void SpriteX8_AND_R(register short x asm("%d0"), register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register short w asm("%d3"),register void *dest asm("%a0")) __attribute__((__regparm__));


void ClipSprite8_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite16_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite32_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0"));


void GraySprite8_AND(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite8_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_AND(short x,short y,short h,unsigned short* sprite1,unsigned short* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite16_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_AND(short x,short y,short h,unsigned long* sprite1,unsigned long* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite32_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySpriteX8_AND(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,short bytewidth,void* dest1,void* dest2) __attribute__((__stkparm__));


void GrayClipSprite8_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_AND_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


SpriteX_AND draw a sprite with a width of X pixels or less on the screen using AND logic. These routines are significantly faster than using SPRT_AND as parameter mode, because these routines have been streamlined for the specific type of logic they employ. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.

The SpriteX8_AND function differs from the rest of the functions. It is not fixed to a specific width, but you can specify the width in bytes as parameter (bytewidth). The sprite data for SpriteX8_AND has to be organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.

NOTE1: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
NOTE2: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void Sprite8_OR(short x,short y,short h,unsigned char *sprt,void *dest) __attribute__((__stkparm__));

void Sprite8_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite16_OR(short x,short y,short h,unsigned short *sprt,void *dest) __attribute__((__stkparm__));

void Sprite16_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite32_OR(short x,short y,short h,unsigned long *sprt,void *dest) __attribute__((__stkparm__));

void Sprite32_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void SpriteX8_OR(short x,short y,short h,unsigned char *sprt,short w,void *dest) __attribute__((__stkparm__));

void SpriteX8_OR_R(register short x asm("%d0"), register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register short w asm("%d3"),register void *dest asm("%a0")) __attribute__((__regparm__));


void ClipSprite8_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite16_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite32_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0"));


void GraySprite8_OR(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite8_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_OR(short x,short y,short h,unsigned short* sprite1,unsigned short* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite16_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_OR(short x,short y,short h,unsigned long* sprite1,unsigned long* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite32_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySpriteX8_OR(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,short bytewidth,void* dest1,void* dest2) __attribute__((__stkparm__));


void GrayClipSprite8_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_OR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


SpriteX_OR draw a sprite with a width of X pixels or less on the screen using OR logic. These routines are significantly faster than using SPRT_OR as parameter mode, because these routines have been streamlined for the specific type of logic they employ. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.

The SpriteX8_OR function differs from the rest of the functions. It is not fixed to a specific width, but you can specify the width in bytes as parameter (bytewidth). The sprite data for SpriteX8_OR has to be organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.

NOTE1: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
NOTE2: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void Sprite8_XOR(short x,short y,short h,unsigned char *sprt,void *dest) __attribute__((__stkparm__));

void Sprite8_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite16_XOR(short x,short y,short h,unsigned short *sprt,void *dest) __attribute__((__stkparm__));

void Sprite16_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite32_XOR(short x,short y,short h,unsigned long *sprt,void *dest) __attribute__((__stkparm__));

void Sprite32_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void SpriteX8_XOR(short x,short y,short h,unsigned char *sprt,short w,void *dest) __attribute__((__stkparm__));

void SpriteX8_XOR_R(register short x asm("%d0"), register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register short w asm("%d3"),register void *dest asm("%a0")) __attribute__((__regparm__));


void ClipSprite8_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite16_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite32_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0"));


void GraySprite8_XOR(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite8_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_XOR(short x,short y,short h,unsigned short* sprite1,unsigned short* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite16_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_XOR(short x,short y,short h,unsigned long* sprite1,unsigned long* sprite2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite32_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySpriteX8_XOR(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,short bytewidth,void* dest1,void* dest2) __attribute__((__stkparm__));


void GrayClipSprite8_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_XOR_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


SpriteX_XOR draw a sprite with a width of X pixels or less on the screen using XOR logic. These routines are significantly faster than using SPRT_XOR as parameter mode, because these routines have been streamlined for the specific type of logic they employ. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.

The SpriteX8_XOR function differs from the rest of the functions. It is not fixed to a specific width, but you can specify the width in bytes as parameter (bytewidth). The sprite data for SpriteX8_XOR has to be organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.

NOTE1: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
NOTE2: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void Sprite8_MASK(short x,short y,short h,unsigned char *sprt,unsigned char *mask,void *dest) __attribute__((__stkparm__));

void Sprite8_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),unsigned char *mask,register void *dest asm("%a0")) __attribute__((__stkparm__));

void Sprite16_MASK(short x,short y,short h,unsigned short *sprt,unsigned short *mask,void *dest) __attribute__((__stkparm__));

void Sprite16_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),unsigned short *mask,register void *dest asm("%a0")) __attribute__((__stkparm__));

void Sprite32_MASK(short x,short y,short h,unsigned long *sprt,unsigned long *mask,void *dest) __attribute__((__stkparm__));

void Sprite32_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),unsigned long *mask,register void *dest asm("%a0")) __attribute__((__stkparm__));

void SpriteX8_MASK(short x,short y,short h,unsigned char *sprt,unsigned char *mask,short bytewidth,void *dest) __attribute__((__stkparm__));

void SpriteX8_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),unsigned char *mask,register short w asm("%d3"),register void *dest asm("%a0")) __attribute__((__stkparm__));


void ClipSprite8_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),unsigned char *mask,register void *dest asm("%a0")) __attribute__((__stkparm__));

void ClipSprite16_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),unsigned short *mask,register void *dest asm("%a0")) __attribute__((__stkparm__));

void ClipSprite32_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),unsigned long *mask,register void *dest asm("%a0")) __attribute__((__stkparm__));


void GraySprite8_MASK(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,unsigned char* mask1,unsigned char* mask2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite8_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,unsigned char *mask0,unsigned char *mask1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_MASK(short x,short y,short h,unsigned short* sprite1,unsigned short* sprite2,unsigned short* mask1,unsigned short* mask2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite16_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,unsigned short *mask0,unsigned short *mask1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_MASK(short x,short y,short h,unsigned long* sprite1,unsigned long* sprite2,unsigned long* mask1,unsigned long* mask2,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite32_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,unsigned long *mask0,unsigned long *mask1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySpriteX8_MASK(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,unsigned char* mask1,unsigned char* mask2,short bytewidth,void* dest1,void* dest2) __attribute__((__stkparm__));


void GrayClipSprite8_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,unsigned char *mask0,unsigned char *mask1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,unsigned short *mask0,unsigned short *mask1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_MASK_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,unsigned long *mask0,unsigned long *mask1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


SpriteX_MASK mask out an area of the screen at x and y by ANDing the mask pointed to by mask. Then SpriteX_MASK draws a sprite with a width of X pixels or less on the screen (on top of the masked area) using OR logic. This routine is much faster than using separate SpriteX commands or functions found in this header. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.
If masked sprites are to be employed it is probably necessary to employ double buffering in order to restore the background when the masked sprite is redrawn.

The SpriteX8_MASK function differs from the rest of the functions. It is not fixed to a specific width, but you can specify the width in bytes as parameter (bytewidth). The sprite data for SpriteX8_MASK has to be organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.

NOTE1: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
NOTE2: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void Sprite8_BLIT(short x,short y,short h,unsigned char *sprt,unsigned char maskval,void *dest) __attribute__((__stkparm__));

void Sprite8_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register unsigned char maskval asm("%d3"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite16_BLIT(short x,short y,short h,unsigned short *sprt,unsigned short maskval,void *dest) __attribute__((__stkparm__));

void Sprite16_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register unsigned short maskval asm("%d3"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite32_BLIT(short x,short y,short h,unsigned long *sprt,unsigned long maskval,void *dest) __attribute__((__stkparm__));

void Sprite32_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register unsigned long maskval asm("%d3"),register void *dest asm("%a0")) __attribute__((__regparm__));

void SpriteX8_BLIT(short x,short y,short h,unsigned char *sprt,unsigned char *maskval,short bytewidth,void *dest) __attribute__((__stkparm__));

void SpriteX8_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),unsigned char *maskval,register short w asm("%d3"),register void *dest asm("%a0")) __attribute__((__stkparm__));

void ClipSprite8_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),unsigned char maskval,register void *dest asm("%a0")) __attribute__((__stkparm__));

void ClipSprite16_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),unsigned short maskval,register void *dest asm("%a0")) __attribute__((__stkparm__));

void ClipSprite32_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),unsigned long maskval,register void *dest asm("%a0")) __attribute__((__stkparm__));

void GraySprite8_BLIT(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,unsigned char maskval,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite8_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,unsigned char maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_BLIT(short x,short y,short h,unsigned short* sprite1,unsigned short* sprite2,unsigned short maskval,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite16_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,unsigned short maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_BLIT(short x,short y,short h,unsigned long* sprite1,unsigned long* sprite2,unsigned long maskval,void* dest1,void* dest2) __attribute__((__stkparm__));

void GraySprite32_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,unsigned long maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySpriteX8_BLIT(short x,short y,short h,unsigned char* sprite1,unsigned char* sprite2,unsigned char* maskval,short bytewidth,void* dest1,void* dest2) __attribute__((__stkparm__));

void GrayClipSprite8_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,unsigned char maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,unsigned short maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_BLIT_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,unsigned long maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

SpriteX_BLIT mask out an area of the screen at x and y by ANDing the mask pointed to by maskval to each destination line. Then SpriteX_BLIT draws a sprite with a width of X pixels or less on the screen (on top of the masked area) using OR logic. This routine is much faster than using separate SpriteX commands or functions found in this header. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.
The BLIT functions are commonly used for background sprites where one wishes to mask out a rectangular array that can be acomplished with the same value for each line of the sprite instead of a full mask sprite.

The SpriteX8_BLIT function differs from the rest of the functions. It is not fixed to a specific width, but you can specify the width in bytes as parameter (bytewidth). The sprite data for SpriteX8_BLIT has to be a byte array organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.



NOTE1: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
NOTE2: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void Sprite8_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite16_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));

void Sprite32_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0")) __attribute__((__regparm__));


void ClipSprite8_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned char *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite16_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned short *sprt asm("%a1"),register void *dest asm("%a0"));

void ClipSprite32_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register unsigned long *sprt asm("%a1"),register void *dest asm("%a0"));


void GraySprite8_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


void GrayClipSprite8_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_RPLC_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


SpriteX_RPLC are SpriteX_BLIT functions with hard-coded white (0) mask and therefore a slightly different prototype.

NOTE1: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
NOTE2: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void GraySprite8_TRANB_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_TRANB_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_TRANB_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite8_TRANB_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_TRANB_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_TRANB_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


GraySpriteX_TRANB draw a grayscale sprite with transparency color black. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprt0 and sprt1 are pointers to the arrays of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest0 and dest1 is the pointer to a video plane of size 240 x 128 pixels. Use function GrayGetPlane to retrieve the pointers to the video planes.
NOTE: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




void GraySprite8_TRANW_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite16_TRANW_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GraySprite32_TRANW_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite8_TRANW_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite16_TRANW_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayClipSprite32_TRANW_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


GraySpriteX_TRANW draw a grayscale sprite with transparency color white. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. sprt0 and sprt1 are pointers to the arrays of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; and for X=32 type is unsigned long) which define the shape of the sprite (line by line). dest0 and dest1 is the pointer to a video plane of size 240 x 128 pixels. Use function GrayGetPlane to retrieve the pointers to the video planes.
NOTE: the functions whose name contains "Clip" are the clipped variants of the normal (single or double plane) functions, the sprites are clipped outside the rectangle whose extreme points are (0,0) and (239,127).




[ENTRELACEES] "GrayClipISprite8/16/32_MASK_R are noticeably faster than GrayClipSprite8/16/32_MASK_R. Indeed, the latter apply the same mask to both planes, the former apply one mask per plane. One mask per plane is more powerful, but bigger, often overkill, and slower. See also TRAN[BW] routines."
  

Fast Sprite Grabbing Routines



void Sprite8Get(short x,short y,short h,void* src,unsigned char* dest) __attribute__((__stkparm__));

void Sprite8Get_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register void* src asm("%a0"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__));

void Sprite16Get(short x,short y,short h,void* src,unsigned short* dest) __attribute__((__stkparm__));

void Sprite16Get_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register void* src asm("%a0"),register unsigned short* dest asm("%a1")) __attribute__((__regparm__));

void Sprite32Get(short x,short y,short h,void* src,unsigned long* dest) __attribute__((__stkparm__));

void Sprite32Get_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register void* src asm("%a0"),register unsigned long* dest asm("%a1")) __attribute__((__regparm__));

void SpriteX8Get(short x,short y,short h,void* src,unsigned char* dest,short bytewidth) __attribute__((__stkparm__));

void SpriteX8Get_R(register short x asm("%d0"),register short y asm("%d1"),register short h asm("%d2"),register void *src asm("%a1"),register unsigned char *dest asm("%a0"),register short bytewidth asm("%d3")) __attribute__((__regparm__));


SpriteXGet copies a sprite from the screen at x and y to dest. This routine is many times faster than the TIOS routine BitmapGet. Additonally sprites retrieved using SpriteXGet can be used as arguments for all the Sprite routines found in this header, unlike the bitmaps obtained with BitmapGet. x and y are the coordinates of the upper left corner of the sprite. h is the height of the sprite. src is a pointer to a video plane of size 240x128 pixels from which one wants to retrieve the sprite. dest is the pointer to a buffer (array) which is large enough to store the fetched sprite data.

The SpriteX8Get function differs from the rest of the functions. It is not fixed to a specific width, but you can specify the width in bytes as parameter (bytewidth). The sprite data fetched by SpriteX8Get is organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.

You can use SpriteX8Get_R twice to simulate "FastCopyRectangleX8_R" (see below the Fast...RectanglesX8_R).


  

SpriteX8 Mirror and Rotate Routines



void SpriteX8_MIRROR_H(short h,unsigned char* src,short bytewidth,unsigned char* dest) __attribute__((__stkparm__));

void SpriteX8_MIRROR_H_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));

void SpriteX8_MIRROR_V(short h,unsigned char* src,short bytewidth,unsigned char* dest) __attribute__((__stkparm__));

void SpriteX8_MIRROR_V_R(register short h asm("%d0"),register unsigned char* src asm("%a1"),register short bytewidth asm("%d2"),register unsigned char* dest asm("%a0")) __attribute__((__regparm__(4)));

void SpriteX8_MIRROR_HV_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));


void SpriteX8X8_ROTATE_RIGHT_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));

void SpriteX8X8_ROTATE_LEFT_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));

void SpriteX8X8_RR_MH_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));

void SpriteX8X8_RL_MH_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));


SpriteX8_MIRROR_H/SpriteX8_MIRROR_V are utility functions which can be used to generate a horizontally or vertically mirrored version of a variable-sized sprite (X8 sprite). The height of the sprite is specified by parameter h and the width in bytes is specified by parameter bytewidth.
SpriteX8_MIRROR_HV_R generates a both horizontally and vertically mirrored version of a X8 sprite.
SpriteX8X8_ROTATE_RIGHT_R/SpriteX8X8_ROTATE_LEFT_R are utility functions which can be used to generate a pi/2 right or left rotated version of a variable-sized square sprite (X8X8 sprite). The height and width of the sprite is specified by parameter bytewidth.
SpriteX8X8_RR_MH_R/SpriteX8X8_RL_MH_R mirror and rotate a square sprite (see extgraph.h to see why these functions exist).


  

Sprite Scaling Routines

Courtesy of Jim Haskell (jimhaskell@yahoo.com)
[routines slightly modified (and bugfixed) to fit the needs]
New (faster) routines by Julien Richard-Foy (julien.rf@wanadoo.fr) are on the way.


void ScaleSprite8_OR(unsigned char *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite16_OR(unsigned short *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite32_OR(unsigned long *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite64_OR(unsigned long long *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

ScaleSpriteX_OR scales a square input sprite with a width of X pixels or less and then draws the scaled sprite on the screen using OR logic. x0 and y0 are the coordinates of the upper left corner of the sprite. sizex and sizey are the desired dimensions of the scaled sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; for X=32 type is unsigned long; and for X=64 type is unsigned long long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.



void ScaleSprite8_AND(unsigned char *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite16_AND(unsigned short *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite32_AND(unsigned long *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite64_AND(unsigned long long *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

ScaleSpriteX_AND scales a square input sprite with a width of X pixels or less and then draws the scaled sprite on the screen using AND logic. x0 and y0 are the coordinates of the upper left corner of the sprite. sizex and sizey are the desired dimensions of the scaled sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; for X=32 type is unsigned long; and for X=64 type is unsigned long long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.



void ScaleSprite8_XOR(unsigned char *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite16_XOR(unsigned short *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite32_XOR(unsigned long *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

void ScaleSprite64_XOR(unsigned long long *sprite,unsigned char *dest,short x0,short y0,short sizex,short sizey);

ScaleSpriteX_XOR scales a square input sprite with a width of X pixels or less and then draws the scaled sprite on the screen using XOR logic. x0 and y0 are the coordinates of the upper left corner of the sprite. sizex and sizey are the desired dimensions of the scaled sprite. sprite is a pointer to the array of unsigned numbers of type equal to X (i.e. for X=8 type is unsigned char; for X=16 type is unsigned short; for X=32 type is unsigned long; and for X=64 type is unsigned long long) which define the shape of the sprite (line by line). dest is the pointer to a video plane of size 240 x 128 pixels. If you want to draw the sprite to the normal video plane you can use constant LCD_MEM for dest. If you are using grayscales use function GrayGetPlane to retrieve the pointer to the video planes.



void DoubleSpriteDimensionsX8_R(register short h asm("%d0"),register unsigned char* src asm("%a0"),register short bytewidth asm("%d1"),register unsigned char* dest asm("%a1")) __attribute__((__regparm__(4)));

void DoubleSpriteDimensions16x16_R(register unsigned short* src asm("%a0"),register unsigned long* dest asm("%a1")) __attribute__((__regparm__(2)));

DoubleSpriteDimensionsX8_R is a fast alternative to ScaleSprite routines if the scale factor is 2. DoubleSpriteDimensions16x16_R was designed for the "AMS native comment format" available since TIGCC 0.95.


  

Plane Scrolling Routines



void ScrollLeft160(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollLeft160_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

void ScrollLeft240(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollLeft240_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

ScrollLeftX scroll X pixels of nr number of lines of a video plane (240x128 pixels in size) 1 pixel to the left.



void ScrollRight160(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollRight160_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

void ScrollRight240(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollRight240_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

ScrollRightX scroll X pixels of nr number of lines of a video plane (240x128 pixels in size) 1 pixel to the right.



void ScrollUp160(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollUp160_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

void ScrollUp240(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollUp240_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

ScrollUpX scroll X pixels of nr number of lines of a video plane (240x128 pixels in size) 1 line upwards.



void ScrollDown160(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollDown160_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

void ScrollDown240(unsigned short* buffer,unsigned short lines) __attribute__((__stkparm__));

void ScrollDown240_R(unsigned short* buffer,unsigned short lines) __attribute__((__regparm__(2)));

ScrollDownX scroll X pixels of nr number of lines of a video plane (240x128 pixels in size) 1 line downwards.


  

Fast CopyScreen Routine



void FastCopyScreen(void* src,void* dest) __attribute__((__stkparm__));

void FastCopyScreen_R(register void* src asm("%a0"),register void* dest asm("%a1")) __attribute__((__regparm__(2)));

FastCopyScreen copies a complete screen (3840 bytes == 240x128 pixels) from buffer src to buffer dest. The implementation is similar to the one used within the actual grayscale support. You can bet it's really fast.

WARNING: Kevin Kofler (kevin.kofler@chello.at) informed me that FastCopyScreen will crash your calculator if src points into the archive memory, for example if you try to copy a screen which is stored in an archived variable. Don't use FastCopyScreen in this case.
In general, I highly recommend using FastCopyScreen_R instead of memcpy: to date, the PedroM memcpy is extremely slow.


  

Fast Line Drawing



void FastDrawLine(unsigned char* plane,short x1,short y1,short x2,short y2,short mode) __attribute__((__stkparm__));

void FastDrawLine_R(register unsigned char* plane asm("%a0"),register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3"),short mode) __attribute__((__stkparm__));

FastDrawLine() is a replacement for the AMS DrawLine function. It's almost 500 percent faster (see demo2), faster than that of graphlib too (ask me for the kernel-based bench if you want it). Valid modes are A_REVERSE, A_NORMAL, A_XOR, A_REPLACE, A_OR (A_NORMAL = A_REPLACE = A_OR is assumed if mode is neither A_REVERSE nor A_XOR).FastDrawLine draws a line from (x1y1) to (x2y2) on a video plane of size 240x128 pixels using attribute mode.



void FastDrawHLine(unsigned char* plane,short x1,short x2,short y,short mode) __attribute__((__stkparm__));

void FastDrawHLine_R(register unsigned char* plane asm("a0"), register short x1 asm("d0"), register short x2 asm("d1"), register short y asm("d2"),short mode) __attribute__((__stkparm__));

FastDrawHLine() draws a horizontal line from point (x1y) to (x2y) on a video plane of size 240x128 pixels using attribute mode. Valid modes are A_REVERSE, A_NORMAL, A_XOR, A_REPLACE, A_OR (A_NORMAL = A_REPLACE = A_OR is assumed if mode is neither A_REVERSE nor A_XOR). If the specified mode is not one of these nothing will be drawn.

NOTE: This function is even more optimized than FastDrawLine and tries to write blocks of 16 points at each loop.



void FastDrawVLine(unsigned char* plane,short x,short y1,short y2,short mode) __attribute__((__stkparm__));

void FastDrawVLine_R(register unsigned char* plane asm("%a0"),register short x asm("%d0"),register short y1 asm("%d1"),register short y2 asm("%d2"),short mode) __attribute__((__stkparm__));

FastDrawVLine() draws a vertical line from point (xy1) to (xy2) on a video plane of size 240x128 pixels using attribute mode. Valid modes are A_REVERSE, A_NORMAL, A_XOR, A_REPLACE, A_OR (A_NORMAL = A_REPLACE = A_OR is assumed if mode is neither A_REVERSE nor A_XOR).



void FastLine_Draw_R(void *plane asm("%a0"),short x1 asm("%d0"),short y1 asm("%d1"),short x2 asm("%d2"),short y2 asm("%d3")) __attribute__((__regparm__));

void FastLine_Erase_R(void *plane asm("%a0"),short x1 asm("%d0"),short y1 asm("%d1"),short x2 asm("%d2"),short y2 asm("%d3")) __attribute__((__regparm__));

void FastLine_Invert_R(void *plane asm("%a0"),short x1 asm("%d0"),short y1 asm("%d1"),short x2 asm("%d2"),short y2 asm("%d3")) __attribute__((__regparm__));

These routines are replacements for the AMS DrawLine function. They're almost 500 percent faster (same speed as FastDrawLine()). The drawing mode is hard-coded into them: A_NORMAL = A_REPLACE = A_OR for FastLine_Draw_R, A_REVERSE for FastLine_Erase_R, A_XOR for FastLine_Invert_R. These routines draw a line from (x1y1) to (x2y2) on a video plane of size 240x128 pixels using hard-coded attribute.


  

Fast Rectangle Drawing



void FastFillRect(unsigned char* plane,short x1,short y1,short x2,short y2,short mode) __attribute__((__stkparm__));

void FastFillRect_R(register unsigned char* plane asm("%a0"),register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3"),short mode) __attribute__((__stkparm__));

void GrayFastFillRect_R(register void* dest1 asm("%a0"),register void* dest2 asm("%a1"), register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3"),short color) __attribute__((__stkparm__));

void FastFilledRect_Draw_R(register unsigned char* plane asm("%a0"),register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3")) __attribute__((__regparm__(5)));

void FastFilledRect_Erase_R(register unsigned char* plane asm("%a0"),register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3")) __attribute__((__regparm__(5)));

void FastFilledRect_Invert_R(register unsigned char* plane asm("%a0"),register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3")) __attribute__((__regparm__(5)));


These routines draw a filled rectangle whose endpoints are (x1;y1) and (x2;y2) in 240x128 plane plane. FastFilledRect_X_R are the one-mode-only versions of FastFillRect (Draw corresponds to mode == A_NORMAL, Erase corresponds to mode == A_REVERSE, Invert corresponds to mode == A_XOR).

void FastOutlineRect(void* plane,short x1,short y1,short x2,short y2,short mode) __attribute__((__stkparm__));

void FastOutlineRect_R(register void* plane asm("%a0"),register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3"),short mode) __attribute__((__stkparm__));

void GrayFastOutlineRect_R(register void* dest1 asm("%a0"),register void* dest2 asm("%a1"), register short x1 asm("%d0"),register short y1 asm("%d1"),register short x2 asm("%d2"),register short y2 asm("%d3"),short color) __attribute__((__stkparm__));


These routines draw an outlined rectangle whose endpoints are (x1;y1) and (x2;y2) in 240x128 plane plane.

void FastEraseRect160_R(register unsigned char* plane asm("%a0"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(3)));

void FastEraseRect240_R(register unsigned char* plane asm("%a0"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(3)));

void GrayFastEraseRect2B160_R(register unsigned char* lightplane asm("%a0"),register unsigned char* darkplane asm("%a1"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(4)));

void GrayFastEraseRect2B240_R(register unsigned char* lightplane asm("%a0"),register unsigned char* darkplane asm("%a1"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(4)));

void FastFillRect160_R(register unsigned char* plane asm("%a0"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(3)));

void FastFillRect240_R(register unsigned char* plane asm("%a0"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(3)));

void GrayFastFillRect2B160_R(register unsigned char* lightplane asm("%a0"),register unsigned char* darkplane asm("%a1"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(4)));

void GrayFastFillRect2B240_R(register unsigned char* lightplane asm("%a0"),register unsigned char* darkplane asm("%a1"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(4)));

void FastInvertRect160_R(register unsigned char* plane asm("%a0"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(3)));

void FastInvertRect240_R(register unsigned char* plane asm("%a0"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(3)));

void GrayFastInvertRect2B160_R(register unsigned char* lightplane asm("%a0"),register unsigned char* darkplane asm("%a1"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(4)));

void GrayFastInvertRect2B240_R(register unsigned char* lightplane asm("%a0"),register unsigned char* darkplane asm("%a1"),register short starty asm("%d0"), register unsigned short lines asm("%d1")) __attribute__((__regparm__(4)));


These routines fill a rectangle with white, black, or invert a rectangle (respectively) whose width is 160 or 240 pixels, and whose height is arbitrary, in a 240x128 plane.

void FastEraseRectX8_R(register unsigned char* plane asm("%a0"),register short startcol asm("%d0"),register short startrow asm("%d1"),register unsigned short nrlines asm("%d2"),register unsigned short bytewidth asm("%d3")) __attribute__((__regparm__(5)));

void FastFillRectX8_R(register unsigned char* plane asm("%a0"),register short startcol asm("%d0"),register short startrow asm("%d1"),register unsigned short nrlines asm("%d2"),register unsigned short bytewidth asm("%d3")) __attribute__((__regparm__(5)));

void FastInvertRectX8_R(register unsigned char* plane asm("%a0"),register short startcol asm("%d0"),register short startrow asm("%d1"),register unsigned short nrlines asm("%d2"),register unsigned short bytewidth asm("%d3")) __attribute__((__regparm__(5)));

FastCopyRectX8_R can be emulated with SpriteX8Get_R and SpriteX8_OR_R.


These routines fill a rectangle with white, black, or invert a rectangle (respectively) whose width and x coordinate is multiple of 8, whose y coordinate is arbitrary, in a 240x128 plane.

FastCopyRectX8_R can be emulated with SpriteX8Get_R and SpriteX8_OR_R.


  

Misc. Grayscale Support Routines

"Gray..." names reflect the new TIGCCLIB naming convention, "...Gray" names are left for compatibility



void GrayClearScreen();

void GrayClearScreen2B(void* lightplane,void *darkplane);

void ClearGrayScreen();

void ClearGrayScreen2B(void* lightplane,void *darkplane);

GrayClearScreen/ClearGrayScreen clears both standard grayplanes at once whereas GrayClearScreen2B/ClearGrayScreen2B clears the specified buffers. Internally it is implemented using a very fast ASM loop which outweights any other approach (memset() for example - especially on PedroM, since to date, the PedroM memset is extremely slow) in speed.
Note that lightplane and darkplane have to be of size 240 x 128 pixels and they have to start at an even address (buffers allocated with malloc always starts at an even address).




void GrayDrawRect(short x0,short y0,short x1,short y1,short color,short fill);

void GrayDrawRect2B(short x0,short y0,short x1,short y1,short color,short fill,void* lightplane,void *darkplane);

void DrawGrayRect(short x0,short y0,short x1,short y1,short color,short fill);

void DrawGrayRect2B(short x0,short y0,short x1,short y1,short color,short fill,void* lightplane,void *darkplane);

DrawGrayRect/DrawGrayRect2B/GrayDrawRect/GrayDrawRect2B draws a rectangle with vertices at (x0,y0), (x1,y0), (x0,y1), and (x1,y1). Parameter color specifies the color of the rectangle. Valid color values are defined by enumeration GrayColors. Parameter fill specifies whether the rect is filled (solid) or just the outline of a rectangle (hollow). Valid arguments for fill are define by enumeration FillAttrs.
GrayDrawRect/DrawGrayRect uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayDrawRect2B/DrawGrayRect2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayInvertRect(short x0,short y0,short x1,short y1);

void GrayInvertRect2B(short x0,short y0,short x1,short y1,void* lightplane,void *darkplane);

void InvertGrayRect(short x0,short y0,short x1,short y1);

void InvertGrayRect2B(short x0,short y0,short x1,short y1,void* lightplane,void *darkplane);

InvertGrayRect/InvertGrayRect2B/GrayInvertRect/GrayInvertRect2B inverts (switches pixels, which are off, on and those, which are on, off) a rectangle with vertices at (x0,y0), (x1,y0), (x0,y1), and (x1,y1).
These functions may be useful in menus where the rect inverted by GrayInvertRect can act as the menu selection bar.
GrayInvertRect/InvertGrayRect uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayInvertRect2B/InvertGrayRect2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayDrawLine(short x0,short y0,short x1,short y1,short color);

void GrayDrawLine2B(short x0,short y0,short x1,short y1,short color,void* lightplane,void *darkplane);

void DrawGrayLine(short x0,short y0,short x1,short y1,short color);

void DrawGrayLine2B(short x0,short y0,short x1,short y1,short color,void* lightplane,void *darkplane);

GrayDrawLine/GrayDrawLine2B/DrawGrayLine/DrawGrayLine2B draws a line with color color from (x0y0) to (x1y1) using the standard AMS routine DrawLine. Valid values of color are defined by enumeration GrayColors.
GrayDrawLine/DrawGrayLine uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayDrawLine2B/DrawGrayLine2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayFastDrawLine(short x0,short y0,short x1, short y1, short color);

void GrayFastDrawLine(short x0,short y0,short x1, short y1, short color);

void FastDrawGrayLine2B(short x0,short y0,short x1,short y1,short color,void* lightplane,void *darkplane);

void FastDrawGrayLine2B(short x0,short y0,short x1,short y1,short color,void* lightplane,void *darkplane);

GrayFastDrawLine/GrayFastDrawLine2B/FastDrawGrayLine/FastDrawGrayLine2B is a grayscale version of the FastDrawLine function in this library, which is a replacement for the AMS DrawLine function. FastDrawLine is almost 500 percent faster than DrawLine which carries over to the grayscale version. GrayFastDrawLine/FastDrawGrayLine draws a line with color color from (x0y0) to (x1y1).Valid values of color are defined by enumeration GrayColors.
GrayFastDrawLine/FastDrawGrayLine uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayFastDrawLine2B/FastDrawGrayLine2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayFastDrawHLine(short x0,short x1, short y, short color);

void GrayFastDrawHLine2B(short x0,short x1,short y,short color,void* lightplane,void *darkplane);

void FastDrawGrayHLine(short x0,short x1, short y, short color);

void FastDrawGrayHLine2B(short x0,short x1,short y,short color,void* lightplane,void *darkplane);

GrayFastDrawGrayHLine/GrayFastDrawHLine2B/FastDrawGrayHLine/FastDrawGrayHLine2B is a grayscale version of the FastDrawHLine function in this library. GrayFastDrawHLine/FastDrawGrayHLine draws a horizontal line with color color from (x0y) to (x1y).Valid values of color are defined by enumeration GrayColors.
GrayFastDrawHLine/FastDrawGrayHLine uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayFastDrawHLine2B/FastDrawGrayHLine2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayDrawChar(short x,short y,char c,short attr);

void GrayDrawChar2B(short x,short y,char c,short attr,void* lightplane,void *darkplane);

void DrawGrayChar(short x,short y,char c,short attr);

void DrawGrayChar2B(short x,short y,char c,short attr,void* lightplane,void *darkplane);

GrayDrawChar/GrayDrawChar2B/DrawGrayChar/DrawGrayChar2B draws character c at a specific (xy) location to both grayscale planes producing a black character. See DrawChar for a description of attribute attr.
GrayDrawChar/DrawGrayChar uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayDrawChar2B/DrawGrayChar2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayDrawStr(short x,short y,char* s,short attr);

void GrayDrawStr2B(short x,short y,char* s,short attr,void* lightplane,void *darkplane);

void DrawGrayStr(short x,short y,char* s,short attr);

void DrawGrayStr2B(short x,short y,char* s,short attr,void* lightplane,void *darkplane);

GrayDrawStr/GrayDrawStr2B/DrawGrayStr/DrawGrayStr2B draws a string s at a specific (xy) location to both grayscale planes producing a black string. See DrawChar for a description of attribute attr.
GrayDrawStr/DrawGrayStr uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayDrawStr2B/DrawGrayStr2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



void GrayDrawStrExt(short x,short y,char* s,short attr,short font);

void GrayDrawStrExt2B(short x,short y,char* s,short attr,short font,void* lightplane,void *darkplane);

void DrawGrayStrExt(short x,short y,char* s,short attr,short font);

void DrawGrayStrExt2B(short x,short y,char* s,short attr,short font,void* lightplane,void *darkplane);

GrayDrawStrExt/GrayDrawStrExt2B/DrawGrayStrExt/DrawGrayStrExt2B draws a string s at a specific (xy) location to both grayscale planes producing a black string using the font font. See DrawChar for a description of attribute attr. GrayDrawStrExt/GrayDrawStrExt2B/DrawGrayStrExt/DrawGrayStrExt2B additonally supports the attributes A_CENTERED and A_SHADOWED, which can be OR’ed (|) to the normal Attributes. If A_CENTERED is used the string will be drawn then centered using the given font to evaluate its length. When A_SHADOWED is used a lightgray shadow will be drawn with +1 pixel offset in all two directions.

For example,
GrayDrawStrExt(0,50,"Welcome!",A_REPLACE | A_CENTERED,F_4x6);
will draw "Welcome!" horizontally centered at line 50 with font F_4x6.

GrayDrawStrExt/DrawGrayStrExt uses the results of GrayGetPlane(LIGHT_PLANE) and GrayGetPlane(DARK_PLANE) as destination planes whereas GrayDrawStrExt2B/DrawGrayStrExt2B uses the given parameters lightplane and darkplane as destination planes.

NOTE: This function uses PortSet internally. So the previously active plane is no longer valid after its call.



  

Misc. Types (Enumerations) for Grayscale Routines



enum GrayColors {COLOR_WHITE=0,COLOR_LIGHTGRAY=1,COLOR_DARKGRAY=2,COLOR_BLACK=3};

Enumeration GrayColors specifies grayscale color values used within the ExtGraph library.



enum FillAttrs {RECT_EMPTY=0,RECT_FILLED};

Enumeration FillAttrs specifies filling types for function DrawGrayRect.



enum ExtAttrs {A_CENTERED=0x40,A_SHADOWED=0x80};

Enumeration FillAttrs specifies extended text drawing attributes used by function DrawGrayStrExt.


  

Fast Pixel Access Macros / utility macros



EXT_PIXOFFSET(x,y)

calculates the byte offset of a pixel within a 240x128 pixels large video plane (used internally by EXT_PIXADDR).

EXT_PIXADDR(plane,x,y)

calculates the byte address of a pixel within a 240x128 pixels large video plane.

EXT_PIXMASK(x)

calculates the byte mask corresponding to a x coordinate within a 240x128 pixels large video plane.

EXT_PIXNBIT(x)

calculates the bit number corresponding to a x coordinate within a 240x128 pixels large video plane.

EXT_PIXUP(address)

subtracts 30 bytes (the width of 1 line in bytes) from given pixel byte address.

EXT_PIXDOWN(address)

adds 30 bytes (the width of 1 line in bytes) to given pixel byte address.

EXT_PIXLEFT_AM(address,mask)

modifies given pixel byte address and pixel mask to target the left neighbour pixel of the active one.

EXT_PIXRIGHT_AM(address,mask)

modifies given pixel byte address and pixel mask to target the right neighbour pixel of the active one.

EXT_SETPIX_AM(address,mask)

sets a pixel using the given byte address and the given mask value.

EXT_CLRPIX_AM(address,mask)

clears a pixel using the given byte address and the given mask value.

EXT_XORPIX_AM(address,mask)

inverts a pixel using the given byte address and the given mask value.

EXT_GETPIX_AM(address,mask)

gets a pixel using the given byte address and the given mask value (NOTE: if the return value is 0 the pixel is not set, otherwise it is set).

EXT_SETPIX_AN(a,offset,n)

sets a pixel using the given plane address, pixel offset from the beginning of plane, pixel number (used internally by EXT_SETPIX).

EXT_CLRPIX_AN(a,offset,n)

clears a pixel using the given plane address, pixel offset from the beginning of plane, pixel number (used internally by EXT_CLRPIX).

EXT_XORPIX_AN(a,offset,n)

inverts a pixel using the given plane address, pixel offset from the beginning of plane, pixel number (used internally by EXT_XORPIX).

EXT_GETPIX_AN(a,offset,n)

gets a pixel using the given plane address, pixel offset from the beginning of plane, pixel number (used internally by EXT_GETPIX) (NOTE: if the return value is 0 the pixel is not set, otherwise it is set).

EXT_SETPIX(plane,x,y)

sets a pixel at position (x,y) within a 240x128 pixels large video plane.

EXT_CLRPIX(plane,x,y)

clears a pixel at position (x,y) within a 240x128 pixels large video plane.

EXT_XORPIX(plane,x,y)

inverts a pixel at position (x,y) within a 240x128 pixels large video plane.

EXT_GETPIX(plane,x,y)

gets a pixel at position (x,y) within a 240x128 pixels large video plane (NOTE: if the return value is 0 the pixel is not set, otherwise it is set).

EXT_SHORTABS(a)

returns the absolute value of given short a.

EXT_LONGABS(a)

returns the absolute value of given long a.

EXT_XCHG(a,b)

exchanges the content of values a and b using the ASM exg instruction.

EXT_LONGSWAP(val)

returns the word swapped value (upper and lower word swapped) of the given long using the ASM swap instruction.


  

Floodfill Routines

Courtesy of Zeljko Juric (zjuric@utic.net.ba)
[routine slightly modified to fit the needs]


void FloodFill(short x,short y,unsigned short shade,void* tmpplane,void* dest) __attribute__((__stkparm__));

void FloodFill_R(short x,short y,unsigned short shade,void* tmpplane,void* dest) __attribute__((__regparm__(5)));

void FloodFillMF(short x,short y,unsigned short shade,void* dest) __attribute__((__stkparm__));

void FloodFillMF_R(short x,short y,unsigned short shade,void* dest) __attribute__((__regparm__(4)));

FloodFill/FloodFillMF fills the interior of an area which enclosed by an arbitrary shaped figure (a cycle, a polygon, etc). Parameter shade is a 16-bit unsigned integer and defines a 4x4 matrix of pixels used to fill the interior (for example: if shade is set to 0xffff the interior is filled completely black). Parameter tmpplane of routine FloodFill has to be a 240 * 128 pixels large "scratch" buffer which is used internally. Routine FloodFillMF doesn't need this additionally parameter, but it utilizes malloc and free to allocate and release the necessary buffer. If speed is crucial you should use routine FloodFill instead of FloodFillMF. x and y specifies a point in the destination plane (dest) from where the filling process should be started. If the pixel at (x,y) is already set the routine returns immediately.
NOTE: Due to the fact that FloodFill utilizes heavily the common program stack for its operation the given tmpplane buffer shouldn't be a local LCD_BUFFER variable, but it should be allocated dynamically by using malloc() like FloodFillMF does internally.





  

Transition effects



void FadeOutToBlack_CWS1_R(register void* lightplane asm("%a0"),register void* darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_CWS1_R(register void* lightplane asm("%a0"),register void* darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToBlack_CCWS1_R(register void* lightplane asm("%a0"),register void* darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_CCWS1_R(register void* lightplane asm("%a0"),register void* darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));


void FadeOutToBlack_LR_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_LR_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToBlack_LR18_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_LR18_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToBlack_LR28_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_LR28_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));


void FadeOutToBlack_RL_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_RL_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToBlack_RL18_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_RL18_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToBlack_RL28_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_RL28_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));


void FadeOutToBlack_TB_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_TB_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));


void FadeOutToBlack_BT_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));

void FadeOutToWhite_BT_R(register void *lightplane asm("%a0"),register void *darkplane asm("%a1"),register short height asm("%d0"),register short bytewidth asm("%d1"),register short wait asm("%d2"));


void GrayIShadowPlanesX16_R(register short height asm("%d0"),register short wordwidth asm("%d1"), register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__regparm__(4)));

void GrayShadowPlanesX16_R(register short height asm("%d0"),register short wordwidth asm("%d1"), register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__regparm__(4)));

void GrayIShadowPlanes240_R(register short height asm("%d0"),register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__regparm__(3)));

void GrayShadowPlanes240_R(register short height asm("%d0"),register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__regparm__(3)));

void GrayIShadowPlanesTo_R(register void *src0 asm("%a0"),register void *src1 asm("%a1"),void *dest0,void *dest1) __attribute__((__stkparm__));

void GrayShadowPlanesTo_R(register void *src0 asm("%a0"),register void *src1 asm("%a1"),void *dest0,void *dest1) __attribute__((__stkparm__));


I suggest reading and executing demo18 for an example of usage (and a hint about the parameter wait, since demo18 contains the wait values which seem to me to turn into the best speed, not too slow, not too fast). I'm unable to describe most of those routines in an interesting and not fastidious way...
Gray(I)ShadowPlanesTo_R act like a combination of GrayIShadowPlanes240_R and FastCopyScreen_R.





  

Other graphical routines







Tile (aligned sprites) routines



void Tile8x8_AND_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned char *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile8x8_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned char *sprite asm("%a1"),register unsigned char maskval asm("%d3"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile8x8_MASK_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned char *sprite asm("%a1"),unsigned char* mask,register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile8x8_OR_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned char *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile8x8_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned char *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile8x8_XOR_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned char *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));


void Tile16x16_AND_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned short *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile16x16_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned short *sprite asm("%a1"),register unsigned short maskval asm("%d3"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile16x16_MASK_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned short *sprite asm("%a1"),unsigned short* mask,register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile16x16_OR_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned short *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile16x16_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned short *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile16x16_XOR_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned short *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));


void Tile32x32_AND_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned long *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile32x32_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned long *sprite asm("%a1"),register unsigned long maskval asm("%d3"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile32x32_MASK_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned long *sprite asm("%a1"),unsigned long* mask,register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile32x32_OR_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned long *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile32x32_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned long *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));

void Tile32x32_XOR_R(register short col asm("%d0"),register short y asm("%d1"),register unsigned long *sprite asm("%a1"),register void *plane asm("%a0")) __attribute__((__stkparm__));


void GrayTile8x8_AND_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,unsigned char maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_MASK_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,unsigned char* mask1,unsigned char* mask2,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_OR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_TRANB_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_TRANW_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile8x8_XOR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprt0,unsigned char *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


void GrayTile16x16_AND_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,unsigned short maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_MASK_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,unsigned short* mask1,unsigned short* mask2,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_OR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_TRANB_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_TRANW_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile16x16_XOR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprt0,unsigned short *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


void GrayTile32x32_AND_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,unsigned long maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_MASK_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,unsigned long* mask1,unsigned long* mask2,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_OR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_TRANB_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_TRANW_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayTile32x32_XOR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprt0,unsigned long *sprt1,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


These routines draw square sprites at coordinates multiple of 8 (Tile8x8) or 16 (Tile16x16, Tile32x32) in 240x128 video planes. The x coordinate col is interpreted as a multiple of 8 or 16 (0 means 0, 1 means 8 for Tile8x8 and 16 for Tile16x16 and Tile32x32), the y coordinate y is arbitrary (within the bounds of the plane, these routines are NOT clipped).
NOTE: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.



void GrayITile8x8_AND_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,unsigned char maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_MASK_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_OR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_TRANB_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_TRANW_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile8x8_XOR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned char *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


void GrayITile16x16_AND_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,unsigned short maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_MASK_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_OR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_TRANB_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_TRANW_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile16x16_XOR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned short *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


void GrayITile32x32_AND_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_BLIT_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,unsigned long maskval,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_MASK_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_OR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_RPLC_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_TRANB_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_TRANW_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));

void GrayITile32x32_XOR_R(register short col asm("%d0"),register short y asm("%d1"),unsigned long *sprite,register void *dest0 asm("%a0"),register void *dest1 asm("%a1")) __attribute__((__stkparm__));


These routines have the same effect as GrayTileX, but they take interlaced sprites.
The interlaced sprite format is as follows:





  

Sprite shadow creating routines


void CreateSpriteIShadow8_R(register short height asm("%d0"),register unsigned char* src0 asm("%a0"),register unsigned char* src1 asm("%a1"),unsigned char* mask, unsigned char* dest0, unsigned char* dest1) __attribute__((__stkparm__));

void CreateSpriteIShadow16_R(register short height asm("%d0"),register unsigned short* src0 asm("%a0"),register unsigned short* src1 asm("%a1"),unsigned short* mask, unsigned short* dest0, unsigned short* dest1) __attribute__((__stkparm__));

void CreateSpriteIShadow32_R(register short height asm("%d0"),register unsigned long* src0 asm("%a0"),register unsigned long* src1 asm("%a1"),unsigned long* mask, unsigned long* dest0, unsigned long* dest1) __attribute__((__stkparm__));

void CreateSpriteIShadowX8_R(register short height asm("%d0"),register short bytewidth asm("%d1"),register unsigned char* src0 asm("%a0"),register unsigned char* src1 asm("%a1"),unsigned char* mask, unsigned char* dest0, unsigned char* dest1) __attribute__((__stkparm__));

void CreateSpriteShadow8_R(register short height asm("%d0"),register unsigned char* src0 asm("%a0"),register unsigned char* src1 asm("%a1"),unsigned char* mask, unsigned char* dest0, unsigned char* dest1) __attribute__((__stkparm__));

void CreateSpriteShadow16_R(register short height asm("%d0"),register unsigned short* src0 asm("%a0"),register unsigned short* src1 asm("%a1"),unsigned short* mask, unsigned short* dest0, unsigned short* dest1) __attribute__((__stkparm__));

void CreateSpriteShadow32_R(register short height asm("%d0"),register unsigned long* src0 asm("%a0"),register unsigned long* src1 asm("%a1"),unsigned long* mask, unsigned long* dest0, unsigned long* dest1) __attribute__((__stkparm__));

void CreateSpriteShadowX8_R(register short height asm("%d0"),register short bytewidth asm("%d1"),register unsigned char* src0 asm("%a0"),register unsigned char* src1 asm("%a1"),unsigned char* mask, unsigned char* dest0, unsigned char* dest1) __attribute__((__stkparm__));

void CreateISpriteIShadow8_R(register short height asm("%d0"),register unsigned char* src asm("%a0"),register unsigned char* dest asm("%a1"));

void CreateISpriteIShadow16_R(register short height asm("%d0"),register unsigned short* src asm("%a0"),register unsigned short* dest asm("%a1"));

void CreateISpriteIShadow32_R(register short height asm("%d0"),register unsigned long* src asm("%a0"),register unsigned long* dest asm("%a1"));

void CreateISpriteShadow8_R(register short height asm("%d0"),register unsigned char* src asm("%a0"),register unsigned char* dest asm("%a1"));

void CreateISpriteShadow16_R(register short height asm("%d0"),register unsigned short* src asm("%a0"),register unsigned short* dest asm("%a1"));

void CreateISpriteShadow32_R(register short height asm("%d0"),register unsigned long* src asm("%a0"),register unsigned long* dest asm("%a1"));


CreateSprite(I)ShadowX_R: use sprite pointed to by src0 and src1 and mask pointed to by mask to create a shadowed sprite (colors are "increased": white -> lightgray, lightgray -> darkgray, darkgray -> black, black -> black), stored in dest0 and dest1.
CreateSprite(I)ShadowX_R: use sprite pointed to by masked interlaced sprite src to create a shadowed sprite (colors are "decreased": white -> white, lightgray -> white, darkgray -> lightgray, black -> darkgray), stored in masked interlaced sprite dest.
The interlaced sprite format is as follows:
These routines provide a convenient way to use shadowed sprites with best run-time performance and lowest size: use Create(I)Sprite(I)ShadowX_R to create shadowed sprites once at startup time (instead of embedding shadowed sprites in your program) and then use OR or MASK routines to display these shadowed sprites. Starting from 2.00 Beta 4, Create(I)Sprite(I)ShadowX_R remain the only routines dealing with SHADOW and ISHADOW mode: Gray(Clip)SpriteX_(I)SHADOW(2)_R were slow, made maintaining ExtGraph even more complicated and mostly useless thanks to Create(I)Sprite(I)ShadowX_R routines.

  

Semi-preshifted sprite routines and macros


void PreshiftSprite16x16(register unsigned short *src asm("%a0"),register unsigned long *dest asm("%a1"));

void PreshiftGrayISprite16x16(register unsigned short *src asm("%a0"),register unsigned long *dest asm("%a1"));

PSprite16x16_OR_R, PSprite16x16_XOR_R, GrayPSprite16x16_OR_R, GrayPSprite16x16_XOR_R macros.


Preshift... functions: preshift non-masked interlaced sprite pointed to by src to buffer pointed to by dest. The buffer must be large enough to hold the preshifted sprite: SIZE_OF_PSPRITE16x16 bytes for a B/W sprite, SIZE_OF_PGSPRITE16x16 bytes for a grayscale sprite.
Macros: draw preshifted sprite pointed to by sprt at coordinates x and y to plane dest (dest0 and dest1 for grayscale sprites).
Due to the huge size of the macros (hundreds of bytes), we suggest using a function containing the macro if you use these macros more than twice. Of course, this will decrease brute force performance.
See the comparison between the various approaches below.






Utility Routines, Macros and Globals


EXTGRAPH_VERSION_STR

global character array (char[]) which holds the extgraph version string (format: "ExtGraph vX.YY")

EXTGRAPH_VERSION_PWDSTR

global character array (char[]) which holds the powered by extgraph version string (format: "powered by ExtGraph vX.YY")

EXTGRAPH_VERSION_MAIN

global short variable which holds the main version number (i.e. 0 for v0.90)

EXTGRAPH_VERSION_SUB

global short variable which holds the sub version number (i.e. 90 for v0.90)




Exepack-Decompression and TTArchive Support



Exepack-Compression is a compression algorithm which was initially developed to compress executables (-pack option of TIGCC compiler) and to generate eBooks for TICT's eBookReader. Everything (tools, sources, headerfiles etc.) which is necessary to use this compression in your own projects can be found in the TIGCC Tools Suite which can be download from the TiCT-HQ at http://tict.ticalc.org.

To make things easier for you I have decided to integrate support for exepack decompression and ttarchives into library ExtGraph. It's no longer necessary nor recommended to include files ttunpack.h and ttarchive.h into your sources. Just include extgraph.h and link against extgraph.a. That's all. To generate the compressed data files and ttarchive files you still need the TIGCC Tools Suite, of course (especially the tools ttpack and ttarchive).



What is the difference of an exepacked file and an ttarchive?

An exepacked file is just a single data file which is compressed using tool ttpack. TTArchive files are, as the name already implies, archives which can hold many entries not just one. Each entry can be compressed using ttpack or any other program before you stuff it into the TTArchive file. Tool ttarchive won't care about the content of the entries at all.



How to get the Pointer to the Beginning of a File?

To use the exepack decompression routine and/or the ttarchive access macros you'll need a pointer to the memory where the external variable is stored first. This can be simply done function like the following:

 
//------------------------------------------------------------------
// returns pointer to start of external variable which name is given
// by fname.
// if variable cannot be found NULL is returned
//
// NOTE: this routine internally locks the variable. Due to the fact
//       that the variable has to be unlocked again if you don't
//       need it anymore, it uses the given pointer to a HANDLE
//       to store the handle of the locked variable in it.
//------------------------------------------------------------------
unsigned char* GetPointerToFile(char* fname,HANDLE* h) {
    SYM_ENTRY*     symptr;
    unsigned char* src;

    if ((symptr = DerefSym(SymFind(SYMSTR(fname))))) {
        *h = symptr->handle;
        if (!(src = (unsigned char*)HLock(*h))) return NULL;
            src+=2;
            return src;
        }
    else {
       return NULL;
    }
}

How to use the ExePack Decompression Routine?

The Exepack decompression routine needs takes two pointers. A source and a destination pointer. The source pointer points to the memory which holds the exepacked destination and the destination pointer should point to a buffer which is large enough to hold the decompressed data. Suppose you have an external variable which hold the compressed data (generated with tool ttpack) and you have already implemented the above function GetPointerToFile(). Then decompressing this file can be easily done with a function like this:


//------------------------------------------------------------------
// decompresses an external variable and returns an allocated buffer
// (don't forget to free the returned buffer)
//
// if an error occurs this function returns NULL
//------------------------------------------------------------------
unsigned char* GetDecompressedData(char* fname) {
    HANDLE         h;
    unsigned char* src = GetPointerToFile(fname,&h);
    unsigned char* dest;

    if (!src) return NULL; // file not found

    // check if data is really exepacked
    if (!ttunpack_valid(src)) {
        HeapUnlock(h);  // data NOT valid - unlock locked variable again!!
        return NULL;
    }

    // allocate buffer for decompressed data
    if (!(dest = malloc(ttunpack_size(src)))) {
        HeapUnlock(h);  // out of memory - unlock locked variable again!!
        return NULL;
    }

    // decompress the data
    if (ttunpack_decompress(src,dest) != TTUNPACK_OKAY) {
        free(dest);
        dest = NULL;
    }

    HeapUnlock(h);
    return dest;
}

How to get an Entry of an TTArchive file?

The first step to retrieve an entry of an archive is to get again a pointer to the start of the external variable which holds the ttarchive. The following code shows how to loop through all entries of an ttarchive which is stored in a variabled called "mydata". Of course, the following loop is not really useful, but it demonstrates almost everything which is necessary to now about TTArchives.

HANDLE         h;
unsigned char* src = GetPointerToFile("mydata",&h);

if (!src) {
    // variable not found !!!
}
else {
   if (ttarchive_valid(src)) {
       unsigned short i;
       unsigned short nr_entries = ttarchive_entries(src); // get number of entries

       for (i=0;i<nr_entries;i++) {
           unsigned char* pointer_to_entry = ttarchive_data(src,i);
           unsigned short size_of_entry    = ttarchive_desc(src,i)->length;
           unsigned char* decompressed;

           //-----------------------------------------------------------------------
           // Now we have a pointer to the entry and we know how large this entry is
           // If the entry is compressed we could easily decompress it like this:
           //-----------------------------------------------------------------------
           if (ttunpack_valid(pointer_to_entry)) {
               // this entry is compressed ...
               if ((decompressed = malloc(ttunpack_size(pointer_to_entry)))) {
                   if (ttunpack_decompress(pointer_to_entry,decompressed) == TTUNPACK_OKAY) {
                        //---------------------------------
                        // entry successfully decompressed.
                        // do something with it.
                        //---------------------------------
                   }
                   free(decompressed); // free allocated memory for decompressed entry again
               }
               else {
                   // out of memory!!
               }
           }

           else {
               // this entry is NOT compressed. Do something else with it ....
           }
       }
   }

   HeapUnlock(h); // unlock variable again ....
}
[The above routines are apriori tested thanks to Malcolm Smith (TRgenius). They used to contain at least one severe bug.]

IMPORTANT NOTE: If your program already uses library ExtGraph in combination with ttunpack.h and/or ttarchive.h from the TIGCC Tools Suite, please REMOVE all #include "ttunpack.h" and #include "ttarchive.h" lines in your sourcecode. Including one of these files is not longer necessary NOR recommended. Just include extgraph.h - that's enough.

BTW: Is anyone out there who may extend the docs about Exepack and TTArchive to become more useful? A short demo, which shows the usage of the decompression and the ttarchive stuff would be nice, too.

If "yes", please send me a mail at thomas.nussbaumer@gmx.net.




Collision Detection Functions and Macros


BOUNDS_COLLIDE(x0,y0,x1,y1,w,h)

Checks if two rectangle areas of width w and height h starting at (x0,y0) and (x1,y1) overlaps. Returns 0 if areas won't overlap.

BOUNDS_COLLIDE8(x0,y0,x1,y1)

Checks if two square areas of width 8 and height 8 starting at (x0,y0) and (x1,y1) overlaps. Returns 0 if areas won't overlap.

BOUNDS_COLLIDE16(x0,y0,x1,y1)

Checks if two square areas of width 16 and height 16 starting at (x0,y0) and (x1,y1) overlaps. Returns 0 if areas won't overlap.

BOUNDS_COLLIDE32(x0,y0,x1,y1)

Checks if two square areas of width 32 and height 32 starting at (x0,y0) and (x1,y1) overlaps. Returns 0 if areas won't overlap.

short TestCollide8(short x0,short y0,short x1,short y1,short h,unsigned char* data0, unsigned char* data1)

short TestCollide8_R(register short x0 asm("%d0"),register short y0 asm("%d1"),register short x1 asm("%d2"),register short y1 asm("%d3"),short height,register unsigned char* data0 asm("%a0"),register unsigned char* data1 asm("%a1")) __attribute__((__stkparm__));

Checks if the content of two sprites of width 8 and height h starting at (x0,y0) and (x1,y1) overlaps. Returns 0 if sprites won't overlap. In difference to the bounds checking macros these functions tests the content of two sprites by shifting the content if necessary and "AND"-ing the data together. If a set pixel overlaps (i.e. is set in both sprites) a collision is detected. This way you can test irregulary shaped sprites for collision and not only rectangular ones. data0 and data1 are pointers to the content of the two sprites. For grayscale sprites it is a good idea to use a special type of mask data for data0 and data1 where every pixel is set which should be involved in testing. A simple way to generate such a mask is to OR the data of the dark plane and the light plane together into one plane. If you use such a mask you'll need to call TestCollide8 only once.

short TestCollide16(short x0,short y0,short x1,short y1,short h,unsigned short* data0, unsigned short* data1)

short TestCollide16_R(register short x0 asm("%d0"),register short y0 asm("%d1"),register short x1 asm("%d2"),register short y1 asm("%d3"),short height,register unsigned short* data0 asm("%a0"),register unsigned short* data1 asm("%a1")) __attribute__((__stkparm__));

Checks if the content of two sprites of width 16 and height h starting at (x0,y0) and (x1,y1) overlaps. Returns 0 if sprites won't overlap. In difference to the bounds checking macros these functions tests the content of two sprites by shifting the content if necessary and "AND"-ing the data together. If a set pixel overlaps (i.e. is set in both sprites) a collision is detected. This way you can test irregulary shaped sprites for collision and not only rectangular ones. data0 and data1 are pointers to the content of the two sprites. For grayscale sprites it is a good idea to use a special type of mask data for data0 and data1 where every pixel is set which should be involved in testing. A simple way to generate such a mask is to OR the data of the dark plane and the light plane together into one plane. If you use such a mask you'll need to call TestCollide16 only once.








A note on reporting bugs...


We tried to do our best to provide something bug-free, but we may have failed (bugs were already found in the early ExtGraph 2.00 betas).
If you believe a sprite function is buggy, could you please test it with the project sprtst.tpr in \src\lib ?
If the function is buggy, the program should show its flaws (several flaws could be missed by the program though) more valueable.
If this test doesn't show the function is buggy, well, then it's probably a problem in your code. One of the most frequent causes of random bugs is writes past the bounds of arrays, on the stack (often triggers Illegal Instruction or Address Error) or in the heap (infinite loop in AMS after the program returns, often in HS_popEStack). Be sure to check the result of dynamic memory allocations, too.
Be sure to use the latest TIGCC 0.95 Betas (>=14). Older versions had nasty bugs, newest versions have an even more optimizing linker and a better IDE.
This could turn into gaining time for both you and us, by not generating/treating pointless bug reports. Thanks in advance.






A note on including ExtGraph in your projects' distributions...


If you distribute ExtGraph within your projects' distributions, please include both extgraph.a and extgraph.h (and tilemap.a / tilemap.h if you use the tilemap engine, preshift.h if you use preshifted sprites). Don't get fooled by the huge size of those files: they are very redundant data, high compression ratios can therefore be achieved on them. The biggest file, extgraph.a, is more than six times smaller after compression with old ZIP format.






Special thanks to...


I'd like to thank the contributors, especially Julien Richard-Foy (jackiechan / Sasume - author of the tilemap engine and various programs, attending the TIGCC/TICT message board on a regular basis) and Geoffrey Anneheim (geogeo - author of PolySnd, Arkanoid Revenge of Doh, Nebulus) once more for their work. ExtGraph would never have been what it is if they had not helped me. My policy is of course to let the contributors work on other projects if they want to, which they do for sure. For example, Julien is now working on kernel-based dynamic graphical library GenLib, in which he took some ideas for the tilemap engine and optimizations on TRANB/W routines (also seen in Phoenix Platinum).







Comparison between the different sprite types...


Type Size of an unmasked 16x16 grayscale sprite Additional memory usage Best choice for Bench (12.0 MHz clock and reset settings assumed; the accuracy of values is 5%) - see demo20 and demo21
Normal non-interlaced sprites 2*32 bytes 0 bytes most games, including not so simple platformers and sidescrollers (Phoenix Platinum, Monster, Venus are sprite-based) usually as fast as normal interlaced sprites (except MASK, which is slower - interlaced MASK are equivalent to non-interlaced SMASK)
Normal interlaced sprites 64 bytes 0 bytes most games, including not so simple platformers and sidescrollers (Phoenix Platinum, Monster, Venus are sprite-based) normal 16x16 gray clipped interlaced sprite routine with 2x2 loops (special version of GrayClipISprite16, not inclued: this was done in order to make a fair comparison, given that the loops in the preshifted sprite functions are unrolled): more than 4500 sprites/sec
Tiles (interlaced or non-interlaced) 2*32 or 64 bytes 0 bytes in conjunction with Scroll... and FastCopyScreen, background of sidescrollers like Phoenix Platinum, Krypton; simple strategy games (although sprite functions are often much better since they are much more flexible) as fast as or faster than completely preshifted sprites
Semi-preshifted sprites 64 bytes 1024 bytes for each sprite (to preshift the sprite) "always redraw everything" (can be not so smart) semi-preshifted 16x16 gray non-clipped sprite routine: around 7500 sprites/sec
Completely preshifted sprites 64 bytes 2048 bytes for each sprite (to preshift the sprite) "always redraw everything" (can be not so smart) completely preshifted 16x16 gray non-clipped sprite routine (not inclued since a single such sprite takes 2 KB !): at least 8500 sprites/sec
Tilemap engine 64 bytes large backbuffers (5440 bytes per plane) complex RPGs, platformers for current version; Beta 4 adds support for still tiles (simplified SimCity, Command And Conquer...). Future versions should add support for animated tiles N/A

Comment:

As you can see above, normal sprite functions are enough most of the time. ExtGraph provides many alternatives: tilemap engine, tile functions, hard brute-force (preshifted sprite macros)... If there are sprites moving on a background which is not refreshed too often, think of fast background save&restore functions







Programming / usage tips...


Three general optimization tips (which you can find with many others in the TICT tutorial S1P9) are:







History

VersionDateChanges
2.00 Beta 425/12/2004removed (I)SHADOW(2) routines: they are nearly useless thanks to Create(I)Sprite(I)Shadow and OR routines (which require a small additional amount of space) and they increase maintenance (more than one quarter of all drawing modes).
added Gray(Clip)S[ame]MASK routines.
added a number of hints in the readme, to help users customizing routines by themselves.
added fast background save&restore routines, with the corresponding demo (demo22): faster replacement for Get + RPLC, i.e. another way to do without redrawing everything all the time. This one can outperform all other approaches under some conditions.
Thanks to the input of Julien, they are better.
fixed once more pixel macros, thanks to Kevin.
added missing "const" keyword to most prototypes: at last, no more warnings about discarded qualifiers.
nearly all occurences of ".data" were replaced by ".text". This suits better to the latest TIGCC Betas (better code with -ffunction-sections -fdata-sections --reorder-sections). No impact on compression ratio.
Reduced length of all label names in most ASM routines (unless this made the routines both unreadable and impossible to maintain). This saved dozens of kilobytes on extgraph.a (up to 500 bytes per function !) and .s sources, and improved compression ratio !
ExtGraph doesn't force global imports (from the external files added with GNU ar) anymore. This saves ~6 KB on the size of extgraph.a and won't interfere with clients anymore. Thanks to Sebastian for the report.
Julien told me about speed optimizations on TRANW and TRANB sprite routines (found in programs by pad and PpHd): +15% for TRANW, + >30 % for TRANB.
small optimization (2 bytes, 4 clocks) on a number of sprite routines. [A and B] is equivalent to [B and A]...
small optimization on several routines: d3 or d4 can be saved to a1 instead of the stack.
fixed long-hidden bugs. Most B/W Sprite32 routines were buggy, thanks to Jesse Frey for the report. I found other long-hidden bugs retesting the entire library.
updated the tilemap engine. The API was reduced somewhat: Julien took out with the most useless modes to reduce maintenance. Two demos were added. However, the tilemap engine is still incompatible with the TIGCCLIB grayscale doublebuffering.
brand-new pure ASM ttunpack routines by Samuel Stearley. The fast version gives a huge speed increase (now over 80 KB/sec !), interesting size decrease (while the routine is definitely optimized for speed, with code inlining, and we did not trade safety for speed and size !) compared to the C routine Greg, him and later I had optimized. The small version is 240 bytes (more than 300 bytes smaller than the other version), but it is slow (~<20 KB/sec).
updated SpriteX8 functions, splitting them into normal and slower versions.
several new routines related to planes (Fill, FillWithGarbage). To be fair, I want to mention that I received suggestions and code from Dave Randall, but I had already thought about implementing such routines, and I made a different implementation.
added GrayFastDrawHLine_R, done by Julien.
probably added bugs, forgot fixes, forgot to mention fixes...
not updated the documentation much: most new functions are not described, some prototypes in this documentation may be wrong, etc... There are several annoying bugs in ExtGraph, and I'm on holiday, so I'm spending some time making a bugfix release
translated and released the todo list.
2.00 Beta 311/06/20044 distributions are now available. .tar.bz2 is not the most powerful format, but it's OS-independent, and significantly reduces the size of the library.
Other large TICT software distributions (mainly TICT-Explorer, TI-Chess, FAT-Engine) will be available in both formats too in next versions.
New (I)SHADOW(2)/ISHADOW/ISHADOW2 sprite, clipped sprite routines; not all 32 pixel-wide sprite routines were written.
demo12 and demo17 now also show the usage of SHADOW2 and ISHADOW2 functions.
New Create(I)Sprite(I)Shadow routines: these routines compute a shadowed sprite from another; this shadowed sprite can be used with OR routines, resulting in a huge speed improvement, since (I)SHADOW(2) routines are rather slow.
Optimized EXT_GETPIX_AN the same way as EXT_SET/CLR/XORPIX_AN, fixed all these macros: they used to have too wide constraints for inline ASM, resulting into nonexistent instructions and therefore errors while building projects.
Improved macro EXT_XCHG: since the asm exg instruction can exchange address registers, address registers are now allowed too.
Semi-preshifted sprite functions / macros are now available (8x8 are lacking).
Rewritten many BLIT_R routines to take blitmask in d3, suppressing the inconsistency.
Rewritten TestCollide... routines in ASM, added __regparm__ versions.
Bugfixed the exepack decompression function introduced in Beta 2, thanks to maeyhem for the report. I decreased the size of the decompression routines a bit by turning two 4-byte branches into 2-byte branches.
Bugfixed SpriteX8 routines (bug reported by Travis Fischer, "Fisch2"), thanks to Julien Richard-Foy and step back to older C routines. They used to trigger Address Errors when both height and bytewidth were odd. The rather quick fix (due to lack of time) turns into slightly slower routines (the larger the sprite is, the higher the difference is). This will be improved in next versions.
Revamped the readme at the root of the distribution.
Documentation update (nearly complete):
  • fixed several problems (missing [END OF BOLD] at the beginning messed up the entire documentation, added [PARAGRAPH] and [END OF PARAGRAPH] everywhere);
  • added prototypes and descriptions;
  • made more compatible with that profusion of browsers (suggestions by Kevin Kofler and Sebastian Reichelt).
  • now using free and native SciTE to edit this documentation (I had to fix the formatting of this changelog though).
  • added tips, comparison between the different approaches.
Changed several directory names to 8.3 format.
2.00 Beta 228/03/2004Tilemap engine widely updated, more functions and power (although currently incompatible with the "real" TIGCCLIB doublebuffering); documentation now in English, thanks to Malcolm Smith (TRGenius) for fixing our translation.
Documentation update started, far from complete.
Added a sprite function test program, see right above.
Added another unpacking routine, the new one doesn't disable interrupts (slower but doesn't mess up grayscale).
demo6 now uses the full 92+/V200 screen.
Fixed various bugs: thanks to Jordan Krage (jmank88), Nicolas Lalevée (hibou), ? (Vertyos) for the report.
Slightly optimized many (Gray)(Clip)SpriteX functions (jackiechan), other optimizations are on the way.
Missing SpriteX8_MIRROR_HV_R written.
New routines (GraySpriteX_SHADOW, transition effects, tile (aligned sprite) routines, (Gray)(Clip)SpriteX_RPLC, non-clipped outlined circle drawing, etc.).
Various other routines are on the way (preshifted sprites, more rectangle-drawing routines, more transition effects...). We're open to suggestions up to some extent, too.
2.00 Beta 119/12/2003Tilemap engine added (documentation currently in French, it will be translated into English ASAP).
Small changes in the documentation.
2.00 "Beta 0"18/12/2003Massive update !
Credits for this version go to:
  • Julien Richard-Foy (jackiechan): the vast majority of sprite routines, the upcoming tilemap engine, new scaling routines, several line routines... He's the main contributor, of course. The majority of the work for this version was done by him.
  • Christophe Molon-Noblot (Ximoon): SpriteX8 routines.
  • Olivier Armand (ExtendeD): generic line routine supporting the three drawing modes (optimized a bit).
  • Lionel Debroux: general maintaining, reorganization of the library, tests.
  • Greg Dietsche, Samuel Stearley: updated unpacking routine (safe and faster). Current hexarray taken from SuperStart.
1.0222/05/2002Stepped back to old version of decompression function, because the new one causes random errors to be thrown.
For TIGCC versions greater than 0.93 all functions are declared with "__attribute__((__stkparm__))" in extgraph.h to work correctly with commandline switch -mregparm
1.0108/05/2002Bug in exepack decompression function fixed. Thanks to MastaZog from the TIGCC Programming Forum for the report.
1.0005/04/2002Address calculations in almost all routines changed for speedup (using 0x1e instead of 0xffffe). Thanks to Francesco Orabona (bremen79@infinito.it) for this suggestion.
Macros for bounding rectangle collision testing (BOUNDS_COLLIDE,BOUNDS_COLLIDE8, BOUNDS_COLLIDE16 and BOUNDS_COLLIDE32) added
Functions for Collision detection (TestCollide8() and TestCollide16()) added
bug in macro EXT_PIXOFFSET (missing brackets) fixed. Thanks to Greg Dietsche (greg@gregd.org) for the report.
Demo11 added which shows how to use the collision detection functions TestCollide8() and TestCollide16()
0.9702/04/2002Function FastDrawVLine() added (thanks Lionel, for the original code)
All functions which takes a color argument optimized by using internally the fact that the color values are bit-flags
Demo1 is built now separately for each calctype to reduce codesize
2 bugs in FastDrawHLine() fixed by Francesco Orabona (bremen79@infinito.it)
0.9525/02/2002FastDrawHLine: missing static keyword for local array added to gain speed and size reduction
Local arrays in scaling function declared static to gain speed and size
ClearGrayScreen2B - converted to ASM file (.s)
FastCopyScreen - converted to ASM file (.s)
Exepack decompression routine added (taken from TIGCC Tools Suite)
ttunpack.h and ttarchive.h integrated into extgraph.h for ease of use
Section about Exepack Decompression and TTArchives added to docs
0.9022/02/2002Demos modified by Lionel Debroux (lionel_debroux@yahoo.fr)
Utilities: EXTGRAPH_VERSION_STR, EXTGRAPH_VERSION_PWDSTR, EXTGRAPH_VERSION_MAIN, EXTGRAPH_VERSION_SUB added
Utilities: CheckHWMatch() and DESIRED_CALCTYPE added
0.8705/02/2002Adaptions to compile correctly with TIGCC 0.93 and beyond
0.8631/07/2001ClearGrayScreen2B and FastCopyScreen converted to pure ASM routines
Function FastDrawHLine added (horizontal line drawing)
Functions FastDrawGrayHLine/FastDrawGrayHLine2B added
Misstyped -w option changed to -W in batch files
Misstyped -w option changed to -W in batch files
All problems reported by -W fixed
Routines DrawGrayChar and DrawGrayChar2B added
Warning added to docs of FastCopyScreen
Grayscale variants of sprite drawing routines added
Documentation of SpriteX_BLIT functions fixed
Typo in macro EXT_PIXADDR fixed (thanks FlashZ for reporting)
0.8031/05/2001Routines FloodFill and FloodFillMF added
Demo8 (floodfill demo) added
Routines SpriteX8_MIRROR_H and SpriteX8_MIRROR_V added
Demo9 (sprite x8 mirror demo) added
ClearGrayScreen re-implemented as very fast ASM loop
Routine FastCopyScreen added
Demo10 (fastcopyscreen demo) added
0.7622/05/2001Format information of wide sprites added to X8 functions
Mis-typed macro DrawGrayRect() fixed
Second bug in treatment of x position in ALL scaling routines fixed
ClearGrayScreen/ClearGrayScreen2B added
SpriteX8_MASK and SpriteX8_BLIT fixed
Usage info changed
0.7517/05/2001All TABs removed from the sources
Grayscale support routines for doublebuffering added (DrawStr2B etc.)
Problems with grayscale support routines fixed
Demo6 and demo7 programs added
Wide sprite routines (SpriteX8_OR/_AND/_XOR/_BLIT/_MASK/Get) added
x position treatment in scaling routines fixed
0.7015/05/2001Fast Pixel Access Macros added
FastDrawLine supports now A_NORMAL, too
DrawGrayStrExt restores now previously active font
Documentation of KronicDeth reformatted and incorporated
0.5107/05/2001Sprite scale routines added
0.5006/05/2001Sprite get routines added
0.3014/04/2001Grayscale routines added (taken from TI-Chess and slightly modified)
0.2013/04/2001Sprite routines added (formerly released as TSE) and library renamed to extgraph
0.1012/04/2001Project started (scroll routines and linedrawing routine)



Library ExtGraph and the documentation since 0.51 were written by Thomas Nussbaumer and Lionel Debroux.
Credits for the documentation up to version 0.51 go to Luke Imhoff (KronicDeth).
Additional credits for Routines and Updates go to Jim Haskell, Zeljko Juric, Lionel Debroux, Julien Richard-Foy (jackiechan / Sasume), Christophe Molon-Noblot (Ximoon), Olivier Armand (ExtendeD), Geoffrey Anneheim (geogeo), Vincent Corfdir (Orage), Greg Dietsche (dietsche), Samuel Stearley.


If you need help, please use the TIGCC Programming Message Board.