The <sprites.h> header file
This header file contains the following functions:
Sprite16 Sprite32 Sprite8
and the following predefined types:
SprtModes
Functions
Puts a sprite which is not wider than 16 pixels on the screen.
Sprite16 puts a sprite which is not wider than 16 pixels on the screen (use Sprite32
for wider sprites). This routine is many times faster than TIOS routines like
DrawIcon, BitmapPut, etc.
x and y are coordinates of the top left corner ot the sprite.
height is the height of the sprite. sprite is the pointer to the array of
unsigned integers which define a shape of the sprite (line by line). vm_addr is the pointer
to the video plane (it should be LCD_MEM if you have not used
grayscale or PortSet function). mode is the drawing
mode, and it may have one of the following values (these constants are defined in enum
SprtModes):
SPRT_XOR | XOR the sprite into a background (used for non-masked sprites) |
SPRT_OR | OR the sprite into a background (used for masked sprites together with SPRT_AND) |
SPRT_AND | AND the sprite into a background (used for masked sprites together with SPRT_OR) |
In fact, you can use one of two techniques to draw sprites:
-
Non-masked sprites. Using this method, the sprites are simply XORed into the background. This
technique was popular in many games on old 8-bit computers. To erase the sprite, it is
enough to call the routine again on the same position.
-
Masked sprites. This is more advanced method, which needs more programming practice,
but produces much better results. Using this method, you first need to erase a
part of the background which occupies a space where the sprite need to be displayed,
then to draw the actual sprite shape. To do this, AND the inverse of the sprite mask
to the background, then OR the sprite at the same location. However, it is not so
easy to restore the background later. For solving this problem, a lot of advanced
methods are developed (like "double-buffering", etc.). These methods are quite
common in advanced ASM games, and they are explained in many ASM tutorials.
Here is a simple example, which first draws a simple "background", then draws a "masked"
sprite (which is simple 8x8 square with solid edges and blank interior) at (30,30):
static unsigned short sprite[] = {0xFF,0x81,0x81,0x81,0x81,0x81,0x81,0xFF};
static unsigned short imask[] = {~0xFF,~0xFF,~0xFF,~0xFF,~0xFF,~0xFF,~0xFF,~0xFF};
int i;
...
for (i = 0; i <= LCD_WIDTH; i++)
DrawLine (i, 0, i, LCD_HEIGHT, A_SHADE_NS); // A simple background
Sprite16 (30, 30, 8, imask, LCD_MEM, SPRT_AND);
Sprite16 (30, 30, 8, sprite, LCD_MEM, SPRT_OR);
Here, the sprite mask is {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
, but it need to
be inverted before passing it to the Sprite16 function. For this purpose, the operator "~" may be
very useful. Note that "~" is "bitwise NOT". Of course, ~0xFF is the same as 0xFF00
(because all elements are 16-bit integers, so 0xFF is in fact 0x00FF), but such notation
makes the program more clear (and it does not increase the code size, because the inverting will
be performed in the compile time). And, if you want to use Sprite32,
notation ~0xFF will still be valid in a long int array. Without such notation, you must use
0xFF00 in Sprite16, but 0xFFFFFF00 in Sprite32. So, notation like
~0xFF is more universal.
Puts a sprite which is not wider than 32 pixels on the screen.
Sprite32 works exactly like Sprite16, but the width of a sprite may be
up to 32 pixels. sprite is now a pointer to the array of unsigned long integers. So,
to define a sprite (or sprite mask), use something like
static unsigned long sprite[] = {0x1345678, 0x90123456, ...};
Of course, instead of garbage like 12345678 etc. you need to insert real
definition of sprite rows (in hex). Use set of 8-digit hex numbers for defining sprites
used in Sprite32 and set of 4-digit hex numbers for sprites used in Sprite16.
See Sprite16 for more info about sprites.
If you want to use sprites wider than 32 pixels (which is not very likely), one solution is to
use DoorsOS and its "put_sprite" function (see Frequently Asked Questions
for more info about how to do it). If you don't want to use DoorsOS, the proposed method depends
of what will be usage of the sprite. If you don't need too fast action, built-in TIOS function
BitmapPut may be good enough. If you need a very fast sprite
routine for very large sprites, then, huh... you must write it by yourself...
Puts a sprite which is not wider than 8 pixels on the screen.
Sprite8 works exactly like Sprite16, but it is dedicated for quite small
sprites which are not wider than 8 pixels. sprite is now a pointer to the array of
bytes (i.e. unsigned chars). So, to define a sprite (or sprite mask), use something like
static unsigned char sprite[] = {...};
See Sprite16 for more info about sprites.
Predefined types
SprtModes is enumerated type for describing possible modes of sprite drawing. It is defined as
enum SprtModes {SPRT_XOR, SPRT_OR, SPRT_AND};