Horizontally flips a sprite, encoded in screen pixel format, mode 1, with interlaced mask.
void cpct_hflipSpriteMaskedM1 (u8 width, u8 height, void* sprite) __z88dk_callee;
(1B C) width | Width of the sprite in bytes (NOT in pixels!). Must be >= 1. |
(1B B) height | Height of the sprite in pixels / bytes (both are the same). Must be >= 1. |
(2B HL) sprite | Pointer to the sprite array (first byte of consecutive sprite data) |
call cpct_hflipSpriteMaskedM1_asm
This function performs an horizontal flipping of the given sprite along with its interlaced mask. To do so, the function inverts the order of the pairs of bytes formed by each mask byte and its associated pixel-definition byte, for all sprite rows. It also inverts pixel order inside each byte of the sprite (be it pixel byte or mask byte). The function expects to receive an sprite in screen pixel format (mode 1), along with its interlaced mask like in this example:
// Example call. Sprite has 16x4 pixels (4x4 bytes) cpct_hflipSpriteMaskedM1(4, 4, sprite); // Operation performed by the call and results (mM, nN: mask values) // // --------------------------------------------------------------- // | Received as parameter | // --------------------------------------------------------------- // | sprite => [mMmM][0123][mMmM][5678][mMmM][HGFE][mMmM][DCBA] | // | [nNnN][9876][nNnN][5432][nNnN][abcd][nNnN][efgh] | // | [mMmM][0123][mMmM][5678][mMmM][HGFE][mMmM][DCBA] | // | [nNnN][9876][nNnN][5432][nNnN][abcd][nNnN][efgh] | // --------------------------------------------------------------- // | Result after flipping | // --------------------------------------------------------------- // | sprite => [MmMm][ABCD][MmMm][EFGH][MmMm][8765][MmMm][3210] | // | [NnNn][hgfe][NnNn][dcba][NnNn][2345][NnNn][6789] | // | [MmMm][ABCD][MmMm][EFGH][MmMm][8765][MmMm][3210] | // | [NnNn][hgfe][NnNn][dcba][NnNn][2345][NnNn][6789] | // ----------------------------------------------------------------------------- // Sprite takes 32 consecutive bytes in memory (4 rows with 8 bytes, 4 mask bytes // and 4 pixel definition bytes, 4 pixels each pixel byte, for a total of // 16x4 = 64 pixels) //
As can be seen on the example, the function modifies the bytes of the sprite in-place. Therefore, the sprite becomes horizontally flipped after the call and will not return to normal status unless another horizontally flipping operation is performed.
This function performs reasonably well compared to cpct_hflipSpriteM1, as time required for doing the flip is a little bit less than doubled, for double amount of bytes. However, for maximum performance, functions making use of memory-aligned conversion tables are advised. Also, having memory-aligned sprites will permit developing even faster versions. In any case, The most important advantage of this function is its reduced size, compared to requiring a function and a 256-bytes aligned table together.
Next example shows a function designed to draw an animated flag that flips right-to-left as if it was being agitated. To do so, every 30 times it is redrawn, it is flipped horizontally to simulate that right-to-left animated movement:
// Draws an animated flag that changes from left-to-right periodically //(every 30 times it is redrawn). Flag is 24x16 mode 1 pixels //(6x16 bytes, 12x16 bytes taking interlaced mask into account) void drawFlag(u8 x, u8 y) { static u8 timesdrawn; // Statically count the number of times the flag has been drawn u8* pvmem; // Pointer to video memory to draw the sprite // Count for a new redraw of the flag and check if it has been // drawn 30 or more times in order to flip it if(++timesdrawn > 30) { // Horizontally flip the flag to animate it cpct_hflipSpriteMaskedM1(6, 16, flagSprite); timesdrawn = 0; } // Draw the flag pvmem = cpct_getScreenPtr(CPCT_VMEM_START, x, y); cpct_drawSpriteMasked(flagSprite, pvmem, 6, 16); }
AF, BC, DE, HL
C-bindings | 80 bytes |
ASM-bindings | 77 bytes |
Case | microSecs (us) | CPU Cycles | ----------------------------------------------------------------------- Even-width | (116WW + 18)H + 16 | (464WW + 72)H + 64 | Odd-width | (116WW + 87)H + 16 | (464WW + 348)H + 64 | ----------------------------------------------------------------------- W=2,H=16 | 2160 | 8640 | W=5,H=32 | 10224 | 40896 | ----------------------------------------------------------------------- Asm saving | -12 | -48 | -----------------------------------------------------------------------
WW = (int)(width/2), H = height