The ExtGraph Library is an add-on to the TIGCC Library (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 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 compiler or cross-compiler for TI-68k
calculators other than TIGCC will support ExtGraph.
The ExtGraph demos were tested on PedroM 0.81. All demos seem to work (although
PedroM 0.81 seems to suffer more from the keyboard rebounds than AMS, but I tested only on VTI) and
show that PedroM uses more efficient algorithms than AMS (in graphical functions - up to 0.80,
PedroM's vital memcpy and memset were very slow): ExtGraph outperforms PedroM on lines by <~10%
and rectangles by >~3x, while it usually outperforms AMS by >~5x on lines and >~7x on
rectangles.
If you find something else that won't compile (especially the optimized pixel macros - bugs were found and fixed many times), please report it to us !
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.
We will not combine the consecutive planes into one double-sized plane for any sprite
routines. Indeed, this approach doesn't have any significant advantage speed-wise or
size-wise compared to the normal method, and 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 (which is screwing up with the tilemap engine),
unless a fork of the TIGCCLIB routine available starting from 2.00 Beta 5 in src/gray.s -
or Grib - is used.
Therefore I've decided to implement these "monsters".
GrayClipISprite8/16_... are speed-optimized by using interlaced sprites and two different
loops to optimize shiftings.
A number of programs (vertical scroller 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.
The tilemap engine is incompatible with the TIGCCLIB grayscale doublebuffering support,
and will most probably remain. If you want to use the ExtGraph tilemap engine with the TIGCCLIB
doublebuffering support, please use the forked support in /src/gray.s (just add the file to the
TIGCC project, or link with it), which is API- and ABI-compatible with the TIGCCLIB one. Kevin's
tilemap engine patch breaks the entire tilemap engine API and ABI, and gives a crappy calling
convention to the functions, as a4 is used (like in a number of rarely-used TIGCCLIB functions),
which prevents using -freg-relative-a4 or global register variables in a4 - that is, the most
efficient ways to access global variables...
The forked support always allocates planes consecutively, even on HW1 (as a side effect, the
routine uses less SMC and is slightly smaller). Right, this consumes more memory on HW1, but in
practice, you couldn't use this memory anyway. Indeed, HW2/3 - most common models - usually run
AMS 2.xx/3.xx, whose maximum amount of available memory is lesser or equal than that of AMS
1.xx/2.xx used on HW1. Not to mention there are more TSRs on AMS 2.xx/3.xx, starting with Kevin's
AutoAlphaLock-Off.
Note that Julien Richard-Foy is making a new grayscale library. It is significantly smaller than
the TIGCCLIB one, its API looks more like that of Genlib in some aspects (framerate synchronization
functions). It can use user-allocated planes, which also enables using the ExtGraph tilemap engine
(his work !) with doublebuffering, provided the planes are allocated consecutively.
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 decompression routines TestCollide8 TestCollide8_R TestCollide16 TestCollide16_Rthe following predefined types:
GrayColors FillAttrs ExtAttrs TTUNPACK_HEADER TTARCHIVE_HEADER TTARCHIVE_ENTRYthe following global variables:
EXTGRAPH_VERSION_STR EXTGRAPH_VERSION_PWDSTR EXTGRAPH_VERSION_MAIN EXTGRAPH_VERSION_SUB EXTGRAPH_VERSION_REVand 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 DEREFSMALL 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
We tried to do our best to provide something bug-free, but we may have failed (many bugs
were found in the previous 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 could show its flaws
(several flaws could be missed by the program though) more valueable. Note that I have
a large test suite for sprite functions.
If this test doesn't show the function is buggy, well, then it's not unlikely that there's
a problem in your code. One of the most frequent causes of random bugs is writes past the
bounds of data section arrays (segfaults on other architectures), of stack arrays (often
triggers Illegal Instruction or Address Error) or in the heap (often an infinite loop in
AMS at the next allocation or after the program returns). Be sure to check the result of
dynamic memory allocations, too.
Be sure to use the TIGCC 0.95 release, or newer (0.96 recommended).
Thanks in advance.
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.
If you modify ExtGraph functions, please mark your versions as modified in a clear way: this lowers
risks of spreading modified versions which don't behave like the original ones.
I'd like to thank the contributors, especially Julien Richard-Foy (jackiechan / Sasume - author of the tilemap engine and various programs) and Geoffrey Anneheim (geogeo - author of PolySnd, Arkanoid Revenge of Doh, Nebulus, GFA Basic, TI-Gen) 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 ideas for the tilemap engine and optimizations on TRANB/W routines (also seen in Phoenix Platinum).