title: "vbmDrawSprite8E" description: TRSE built-in method (from IDE help)
vbmDrawSprite8E
Systems: VIC20
Parameters: a, a
vbmDrawSprite8E( [address1], [address2] );
- [address1] - pre-shifted address table for the left side of an 8x8 sprite
- [address2] - pre-shifted address table for the right side of an 8x8 sprite
Description
A simple sprite routine to display an 8x8 sprite on the bitmap using an EOR operation. The EOR operation will merge the sprite with the bitmap without destroying the bitmap, but it will look 'noisy' when pixels overlap. The way EOR works is:
- If both the sprite and bitmap have no pixel - no pixel is drawn
- If the sprite has a pixel but the bitmap does not - a pixel is drawn
- If the bitmap has a pixel but the sprite does not - a pixel is drawn
- If both the sprite and the bitmap has a pixel - a pixel is cleared
A side effect of this is that EOR can be used to both draw and remove the sprite without destroying what was already on the bitmap. When a sprite overlaps other pixels, the pxiel will clear which will look a bit noisy, but when drawn again, the sprite is removed and previous pixels restored. See example below.
Only two parameters are required; the addresses of the pre-shifted 'address table' for the left and right side of a sprite. The pre-shifted address table is a list of addresses to point to where each pre-shifted frame can be found in memory.
For example: $a000, $a080, $a1000, $a180
The address table will need to be defined if you import your sprites already pre-shifted. If you use the vbmSpriteShiftL / R commands, these will build the address table for you.
Limitations
Some compromises have been made for the basic 8x8 sprite command.
Firstly, it will write the sprite to wherever the built in screenmemory zero page pointer is pointing to. This could be partly outside of the bitmap memory ($1100 to $1FFF) if you position your sprite off of the screen edges. Therefore, do not use this command if you wish to place sprite your sprite partly off the screen.
Secondly, this sprite command cannot be used with the vbmScrollLeft / Right commands which re-arrange the character map used for the bitmap.
Should either of the above be requirements, use vbmSpriteSlice instead which allows you to draw each sprite column seperately and you can specify the start and end line of the sprite to draw. As such you can only draw the columns and lines as needed in the correct locations.
There are three ways to draw a sprite:
- vbmDrawSprite8 - draws a sprite, merging it with the bitmap
- vbmDrawSprite8E - draws a sprite, merging it with the bitmap using the EOR operation
- vbmClearSprite8 - clears a sprite from the bitmap, effectively 'cutting it out'
Example
x,y :byte;
// define a sprite character
spr8 : array[] of byte = (
%11111111,
%10000001,
%00111100,
%00100100,
%00100100,
%00111100,
%10000001,
%11111111
);
// where to store the pre-shifted addresses of the sprite
spr8L0 : array[8] of integer; // to store the low addresses of pre-shifted sprites for spr8
spr8R0 : array[8] of integer; // to store the high addresses of pre-shifted sprites for spr8
...
// sprite 8x8 - pre-shift in 8 positions, using 64 bytes ($40)
// pre-shift the right side
vbmSpriteShiftR( spr8, ^$a000, 1, 8, spr8L0 ); // spr8 into addr A000, 1 pixel increments, 8 lines
// pre-shift the left side
vbmSpriteShiftL( spr8, ^$a040, 1, 8, spr8R0 ); // spr8 into addr A040, 1 pixel increments, 8 lines
y := 10;
for x := 0 to 100 do
begin
vbmSetPosition1( x, y ); // position the sprite, 1 pixel increments
vbmDrawSprite8E( spr8L0, spr8R0 ); // draw the sprite with EOR
waitforraster( 0 ); // wait for raster
vbmSetPosition1( x, y ); // position the sprite, 1 pixel increments
vbmDrawSprite8E( spr8L0, spr8R0 ); // redraw the sprite with EOR - restoring the bitmap
end;
See also
- vbmDrawSprite16
- vbmSetPosition1 / 2 / 4