Library ExtGraph  -  Documentation

Version 1.02

Extended Graphic Routines for TIGCC Projects

Release Date: 22/05/2002 (Official Release)



PREFACE:

The ExtGraph Library is an AddOn of the TIGCCLIB. 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 maximum speed in mind.

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. To reduce the number of parameters it would be necessary to switch to a special sprite format (for example: the format used by GenLib) and to combine the output buffers into one double-sized array. The change of the sprite format would irritate users of the TIGCCLIB whereas the combination of the output buffers would lack the possibility to draw directly to the grayscale outputscreen, because the buffers used by the TIGCCLIB grayscale routine are not combined in this way. Therefore I've decided to implement these "monsters" yet (until I'll find a better, but still general way).


Contents


Functions, Types, Globals and Macros

Library ExtGraph contains the following functions:
Sprite8_OR              Sprite16_OR             Sprite32_OR             SpriteX8_OR
GraySprite8_OR          GraySprite16_OR         GraySprite32_OR         GraySpriteX8_OR
Sprite8_AND             Sprite16_AND            Sprite32_AND            SpriteX8_AND
GraySprite8_AND         GraySprite16_AND        GraySprite32_AND        GraySpriteX8_AND
Sprite8_XOR             Sprite16_XOR            Sprite32_XOR            SpriteX8_XOR
GraySprite8_XOR         GraySprite16_XOR        GraySprite32_XOR        GraySpriteX8_XOR
Sprite8_MASK            Sprite16_MASK           Sprite32_MASK           SpriteX8_MASK
GraySprite8_MASK        GraySprite16_MASK       GraySprite32_MASK       GraySpriteX8_MASK
Sprite8_BLIT            Sprite16_BLIT           Sprite32_BLIT           SpriteX8_BLIT
GraySprite8_BLIT        GraySprite16_BLIT       GraySprite32_BLIT       GraySpriteX8_BLIT

Sprite8Get              Sprite16Get             Sprite32Get             SpriteX8Get

SpriteX8_MIRROR_H       SpriteX8_MIRROR_V

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

ScrollLeft160           ScrollLeft240
ScrollRight160          ScrollRight240
ScrollUp160             ScrollUp240
ScrollDown160           ScrollDown240

FastCopyScreen
FastDrawLine
FastDrawHLine
FastDrawVLine

ClearGrayScreen         ClearGrayScreen2B
DrawGrayRect            DrawGrayRect2B
InvertGrayRect          InvertGrayRect2B
DrawGrayLine            DrawGrayLine2B
FastDrawGrayLine        FastDrawGrayLine2B
FastDrawGrayHLine       FastDrawGrayHLine2B
DrawGrayChar            DrawGrayChar2B
DrawGrayStr             DrawGrayStr2B
DrawGrayStrExt          DrawGrayStrExt2B
FloodFill               FloodFillMF

UnpackBuffer (or) ttunpack_decompress

TestCollide8            TestCollide16


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:
EXT_PIXADDR
EXT_PIXMASK
EXT_SETPIX
EXT_CLRPIX
EXT_XORPIX
EXT_GETPIX
EXT_PIXUP_AM
EXT_PIXDOWN_AM
EXT_PIXLEFT_AM
EXT_PIXRIGHT_AM
EXT_SETPIX_AM
EXT_CLRPIX_AM
EXT_XORPIX_AM
EXT_GETPIX_AM

CheckHWMatch()
DESIRED_CALCTYPE

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




How to use the ExtGraph Library?



[Information valid until ExtGraph will become part of the TIGCCLIB]

Copy file extgraph.a and file extgraph.h 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. Simple, isn't it?
  

Fast Sprite Drawing Routines



void Sprite8_OR(short x,short y,short h,unsigned char* sprite,void* dest);

void Sprite16_OR(short x,short y,short h,unsigned short* sprite,void* dest);

void Sprite32_OR(short x,short y,short h,unsigned long* sprite,void* dest);

void SpriteX8_OR(short x,short y,short h,unsigned char* sprite,short bytewidth,void* dest);

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

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

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

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

SpriteX_OR draw a sprite with a width of X pixels or less on the screen using OR logic. These routines are many times faster than using SPRITE_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 GetPlane 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.

NOTE: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.



void Sprite8_AND(short x,short y,short h,unsigned char* sprite,void* dest);

void Sprite16_AND(short x,short y,short h,unsigned short* sprite,void* dest);

void Sprite32_AND(short x,short y,short h,unsigned long* sprite,void* dest);

void SpriteX8_AND(short x,short y,short h,unsigned char* sprite,short bytewidth,void* dest);

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

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

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

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

SpriteX_AND draw a sprite with a width of X pixels or less on the screen using AND logic. These routines are many times faster than using SPRITE_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 GetPlane 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.

NOTE: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.



void Sprite8_XOR(short x,short y,short h,unsigned char* sprite,void* dest);

void Sprite16_XOR(short x,short y,short h,unsigned short* sprite,void* dest);

void Sprite32_XOR(short x,short y,short h,unsigned long* sprite,void* dest);

void SpriteX8_XOR(short x,short y,short h,unsigned char* sprite,short bytewidth,void* dest);

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

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

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

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

SpriteX_XOR draw a sprite with a width of X pixels or less on the screen using XOR logic. These routines are many times faster than using SPRITE_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 GetPlane 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.

NOTE: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.



void Sprite8_MASK(short x,short y,short h,unsigned char* sprite,unsigned char* mask,void* dest);

void Sprite16_MASK(short x,short y,short h,unsigned short* sprite,unsigned short* mask,void* dest);

void Sprite32_MASK(short x,short y,short h,unsigned long* sprite,unsigned long* mask,void* dest);

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

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);

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);

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);

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);

SpriteX_MASK masks 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 many times 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 GetPlane to retrieve the pointer to the video planes.
If masked sprites are to be employed it is probably neccassary 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.

NOTE: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.



void Sprite8_BLIT(short x,short y,short h,unsigned char* sprite,unsigned char maskval,void* dest);

void Sprite16_BLIT(short x,short y,short h,unsigned short* sprite,unsigned short maskval,void* dest);

void Sprite32_BLIT(short x,short y,short h,unsigned long* sprite,unsigned long maskval,void* dest);

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

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

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

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

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

SpriteX_BLIT masks 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 many times 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 GetPlane 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 organized like this (example for bytewidth == 3): line1/byte1, line1/byte2, line1/byte3, line2/byte1, line2/byte2, line2/byte3 etc.

Additionally note that the mask value for SpriteX8_BLIT (maskval) has to be given as byte array in difference to the single mask values used by the other BLIT functions.

NOTE: the functions prefixed with "Gray" are the grayscale variants of the normal (single plane) functions.
  

Fast Sprite Grabbing Routines



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

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

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

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

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.
  

SpriteX8 Mirror Routines



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

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

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.
  

Sprite Scaling Routines

Courtesy of Jim Haskell (jimhaskell@yahoo.com)
[routines slightly modified (and bugfixed) to fit the needs]


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 GetPlane 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 GetPlane 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 GetPlane to retrieve the pointer to the video planes.
  

Plane Scrolling Routines



void ScrollLeft160(unsigned short* buffer,unsigned short nr);

void ScrollLeft240(unsigned short* buffer,unsigned short nr);

ScrollLeftX scrolls 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);

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

ScrollLeftX scrolls 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);

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

ScrollLeftX scrolls 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);

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

ScrollLeftX scrolls 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);

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.
  

Fast Line Drawing



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

FastDrawLine() is a replacement of the AMS DrawLine function. It's almost 300 percent faster. Valid modes are A_REPLACE,A_NORMAL,A_REVERSE,A_XOR. If the specified mode valid is not one of these nothing will be drawn. 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);

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_REPLACE,A_NORMAL,A_REVERSE,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);

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_NORMAL,A_REVERSE,A_XOR. If the specified mode is not one of these A_XOR is used (NOTE: A_REPLACE is NOT valid for FastDrawVLine()).

  

Misc. Grayscale Support Routines



void ClearGrayScreen();

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

ClearGrayScreen clears both standard grayplanes at once whereas ClearGrayScreen2B clears the specified buffers. Internally its implemented using a very fast ASM loop which outweights any other approach (like using memset()) 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, BTW).



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 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.
DrawGrayRect uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 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 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 InvertGrayRect can act as the menu selection bar.
InvertGrayRect uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 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);

DrawGrayLine/DrawGrayLine2B draws a line with color color from (x0y0) to (x1y1) using the standard AMS routine. Valid values of color are defined by enumeration GrayColors.
DrawGrayLine uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 FastDrawGrayLine(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);

FastDrawGrayLine/FastDrawLine2B is a grayscale version of the FastDrawLine function in this library, which is a replacement for the AMS DrawLine function. FastDrawLine is almost 300 percent faster than DrawLine which carries over to the grayscale version. FastDrawGrayLine draws a line with color color from (x0y0) to (x1y1).Valid values of color are defined by enumeration GrayColors.
FastDrawGrayLine uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 FastDrawGrayHLine(short x0,short x1, short y, short color);

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

FastDrawGrayHLine/FastDrawHLine2B is a grayscale version of the FastDrawHLine function in this library. FastDrawGrayHLine draws a horizontal line with color color from (x0y) to (x1y).Valid values of color are defined by enumeration GrayColors.
FastDrawGrayHLine uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 DrawGrayChar(short x,short y,char c,short attr);

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

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.
DrawGrayChar uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 DrawGrayStr(short x,short y,char* s,short attr);

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

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.
DrawGrayStr uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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 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);

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. 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,
DrawGrayStrExt(0,50,"Welcome!",A_REPLACE | A_CENTERED,F_4x6);
will draw "Welcome!" horizontally centered at line 50 with font F_4x6.

DrawGrayStrExt uses the results of GetPlane(0) and GetPlane(1) as destination planes whereas 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=1,COLOR_LIGHTGRAY=2,COLOR_DARKGRAY=4,COLOR_BLACK=8};

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



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 to a corresponding x coordinate within a 240x128 pixels large video plane

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)

xor's 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_PIXUP_AM(address)

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

EXT_PIXDOWN_AM(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)

XOR's 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).
  

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);

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

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.


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)

DESIRED_CALCTYPE

a define which holds one of the following strings "TI89","TI92+" or "TI89/92+" depending on the desired calculator type of a program (NOTE: for correct work make sure that USE_TI89 and/or USE_TI92P are set BEFORE extgraph.h gets included).

CheckHWMatch()

A quite useful macro which returns 1 if the calculator type a program runs on matches the calculator type it was compiled for. This may be use used to protect TI89 programs to run on a TI92+ and to protect TI92+ programs to run on a TI89 (NOTE: for correct work make sure that USE_TI89 and/or USE_TI92P are set BEFORE extgraph.h gets included). To use it, you can insert a block like the following into your main routine:
 if (!CheckHWMatch()) {
     ST_helpMsg("ERROR: can only run on a "DESIRED_CALCTYPE);
     return;
 }
If you use lowlevel keyboard reading this protecting against the work calctype is important. Otherwise the user of your program may not exit your program anymore (depending on what keycode is queried by your program).


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 easy for you I have decided to integrate support for exepack decompression and ttarchives into library ExtGraph. It's no longer necessary nor recommented to include file 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) {
    char           tmpstr[40];
    SYM_ENTRY*     symptr;
    unsigned char* src;

    tmpstr[0] = 0;

    if ((symptr = DerefSym(SymFind(strcpy(tmpstr + 1, fname) + strlen(fname))))) {
        *h = symptr->handle;
        if (!(src = 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(src))) {
                   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 completely untested. Maybe they contain typos or "logical" bugs !!!]

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 recommented. 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)

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)

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.


History

VersionDateChanges
1.0222/05/2002Stepped back to old version of decompression function, because the new one causes "random" ERR_Throw's.
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. Thanx 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). Thanx 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. Thanx to G. Dietsche (dietsche39@hotmail.com) for the report.
Demo11 added which shows how to use the collision detection functions TestCollide8() and TestCollide16()
0.9702/04/2002function FastDrawVLine() added (thanx, 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 (thanx 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
misstyped 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.
Credits for the documentation up to version 0.51 go to Luke Imhoff.
Additionally Credits for Routines and Updates go to Jim Haskell, Zeljko Juric and Lionel Debroux.

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