Horizontally flips a sprite, encoded in screen pixel format, mode 0, with interlaced mask.
void cpct_hflipSpriteMaskedM0 (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_hflipSpriteMaskedM0_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 0), along with its interlaced mask like in this example:
// Example call. Sprite has 8x4 pixels (4x4 bytes) cpct_hflipSpriteMaskedM0(4, 4, sprite); // Operation performed by the call and results (mM, nN = mask data bytes) // // --------------------------------------------------------------------------------------------- // | Received as parameter | Result after flipping | // --------------------------------------------------------------------------------------------- // | sprite => [mM][05][nN][21][mM][73][nN][40] | sprite => [Nn][04][Mm][37][Nn][12][Mm][05] | // | [mM][52][nN][23][mM][37][nN][74] | [Nn][47][Mm][73][Nn][32][Mm][25] | // | [mM][05][nN][11][mM][31][nN][04] | [Nn][04][Mm][13][Nn][11][Mm][50] | // | [mM][00][nN][55][mM][44][nN][00] | [Nn][00][Mm][44][Nn][55][Mm][00] | // --------------------------------------------------------------------------------------------- // Sprite takes 32 consecutive bytes in memory: 4 rows with 8 bytes (4 bytes pixel data, // and 4 bytes mask data) //
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_hflipSpriteM0, 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 how to create a function for drawing a 2D-Character sprite that can look either to the left or to the right. Sprite is only flipped when the character changes the side it is looking.
// Draws the main character sprite always looking to the // appropriate side (right or left), reversing it whenever required void drawCharacter(u8 lookingat, u8 x, u8 y) { u8* pvmem; // Pointer to video memory to draw the sprite // Check if we have to reverse character sprite or not if(lookingAt != wasLookingAt) { // Horizontally flip character's sprite when it // changes the side it is looking at cpct_hflipSpriteMaskedM0(4, 8, characterSprite); wasLookingAt = lookingAt; } // Draw main character's sprite pvmem = cpct_getScreenPtr(CPCT_VMEM_START, x, y); cpct_drawSpriteMasked(characterSprite, pvmem, 4, 8); }
AF, BC, DE, HL
C-bindings | 62 bytes |
ASM-bindings | 59 bytes |
Case | microSecs (us) | CPU Cycles | ----------------------------------------------------------------------- Even-width | (80WW + 18)H + 16 | (320WW + 72)H + 64 | Odd-width | (80WW + 69)H + 16 | (320WW + 244)H + 64 | ----------------------------------------------------------------------- W=2,H=16 | 1584 | 6336 | W=5,H=32 | 7344 | 29376 | ----------------------------------------------------------------------- Asm saving | -12 | -48 | -----------------------------------------------------------------------
WW = (int)(width/2), H = height