Draws an sprite to video memory (or to a screen buffer), making use of a given 256-bytes aligned mask table to create transparencies.
C Definition
void cpct_drawSpriteMaskedAlignedTable (const void* psprite, void* pvideomem, u8 width, u8 height, const void* pmasktable) __z88dk_callee;
Input Parameters (6 bytes)
(2B BC) psprite | Source Sprite Pointer |
(2B DE) pvideomem | Destination video memory pointer |
(1B IXL) width | Sprite Width in bytes (>0) (Beware, not in pixels!) |
(1B IXH) height | Sprite Height in bytes (>0) |
(2B HL) pmasktable | Pointer to the aligned mask table used to create transparency |
Assembly call (Input parameters on registers)
call cpct_drawSpriteMaskedAlignedTable_asm
Parameter Restrictions
- sprite must be an array containing sprite’s pixels data in screen pixel format Sprite must be rectangular and all bytes in the array must be consecutive pixels, starting from top-left corner and going left-to-right, top-to-bottom down to the bottom-right corner. Total amount of bytes in pixel array should be width x height. You may check screen pixel format for mode 0 (cpct_px2byteM0) and mode 1 (cpct_px2byteM1) as for mode 2 is linear (1 bit = 1 pixel).
- pvideomem could be any place in memory, inside or outside current video memory. It will be equally treated as video memory (taking into account CPC’s video memory disposition). This lets you copy sprites to software or hardware backbuffers, and not only video memory.
- width must be the width of the sprite in bytes and must be 1 or more. Using 0 as width parameter for this function could potentially make the program hang or crash. Always remember that the width must be expressed in bytes and not in pixels. The correspondence is:
mode 0 | 1 byte = 2 pixels |
modes 1 / 3 | 1 byte = 4 pixels |
mode 2 | 1 byte = 8 pixels |
- height must be the height of the sprite in bytes, and must be greater than 0. There is no practical upper limit to this value. Height of a sprite in bytes and pixels is the same value, as bytes only group consecutive pixels in the horizontal space.
- pmasktable must be a pointer to the mask table that will be used for calculating transparency. A mask table is expected to be 256-sized containing all the possible masks for each possible byte colour value. Also, the mask is required to be 256-byte aligned, which means it has to start at a 0x??00 address in memory to fit in a complete 256-byte memory page. <cpct_transparentMaskTable00M0> is an example table you might want to use.
Known limitations
- This function does not do any kind of boundary check or clipping. If you try to draw sprites on the frontier of your video memory or screen buffer if might potentially overwrite memory locations beyond boundaries. This could cause your program to behave erratically, hang or crash. Always take the necessary steps to guarantee that you are drawing inside screen or buffer boundaries.
- As this function receives a byte-pointer to memory, it can only draw byte-sized and byte-aligned sprites. This means that the box cannot start on non-byte aligned pixels (like odd-pixels, for instance) and their sizes must be a multiple of a byte (2 in mode 0, 4 in mode 1 and 8 in mode 2).
- This function cannot be run from ROM as it uses self-modifying code.
- If mask table is not aligned within a memory page (256-bytes aligned), rubbish may appear on the screen.
- Under hardware scroll conditions, sprite drawing will fail if asked to draw near 0x?7FF or 0x?FFF addresses (at the end of each one of the 8 pixel lines), as next screen byte at that locations is -0x7FF and not +1 bytes away.
Details
This function draws a generic width x height bytes sprite either to video memory or to a back buffer, creating transparencies using a given mask table. In order to create a valid mask table for this function you may use cpctm_createTransparentMaskTable macro.
The original sprite must be stored as an array (i.e. with all of its pixels stored as consecutive bytes in memory). It works in a similar way to cpct_drawSpriteMasked, but taking care about transparency information. For detailed information about how sprite copying works, and how video memory is formatted, take a look at cpct_drawSprite and cpct_drawSpriteMasked.
The way if works is by getting sprite bytes one by one, operating with them, and copying them to video memory (or backbuffer). Each byte got is used as index to retrieve the associated mask value from the mask table. Then, an AND operation between the byte and the mask is done to remove (set to 0) background pixels. After that, an OR operation between the new byte information and the background (the present byte at video memory location where we want to write) is performed. That effectively mixes sprite colours with background colours, after removing background pixels from the sprite.
Destroyed Register values
AF, BC, DE, HL
Required memory
C-bindings | 59 bytes |
ASM-bindings | 45 bytes |
Time Measures
Case | microSecs (us) | CPU Cycles
----------------------------------------------------------------
Best | 28 + (22 + 19W)H + 10HH | 102 + (88 + 76W)H + 40HH
Worst | Best + 10 | Best + 40
----------------------------------------------------------------
W=2,H=16 | 998 / 1008 | 3992 / 4032
W=4,H=32 | 3194 / 3204 | 12776 / 13816
----------------------------------------------------------------
Asm saving | -32 | -128
----------------------------------------------------------------
W = width in bytes, H = height in bytes, HH = [(H-1)/8]