Horizontally flips a sprite, encoded in screen pixel format, mode 1.
void cpct_hflipSpriteM1 (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_hflipSpriteM1_asm
This function performs an horizontal flipping of the given sprite. To do so, the function inverts byte-order in all sprite rows, and also inverts pixel order inside each byte of the sprite. The function expects to receive an sprite in screen pixel format (mode 1), like in this example:
// Example call. Sprite has 16x4 pixels (4x4 bytes) cpct_hflipSpriteM1(4, 4, sprite); // Operation performed by the call and results // // ----------------------------------------------------------------------------- // | Received as parameter | Result after flipping | // ----------------------------------------------------------------------------- // | sprite => [0123][5678][HGFE][DCBA] | sprite => [ABCD][EFGH][8765][3210] | // | [9876][5432][abcd][efgh] | [hgfe][dcba][2345][6789] | // | [0123][5678][HGFE][DCBA] | [ABCD][EFGH][8765][3210] | // | [9876][5432][abcd][efgh] | [hgfe][dcba][2345][6789] | // ----------------------------------------------------------------------------- // Sprite takes 16 consecutive bytes in memory (4 rows with 4 bytes, // and 4 pixels each byte, for a total of 16x4 pixels, 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 has a high performance if taking into account that it is not using a conversion table. However, it is very slow compared to functions that use memory-aligned conversion tables. The advantage is that this function takes less memory space as it does not require the 256-bytes table to be held in memory. Therefore, the main use for this function is to save space in memory whenever fast flipping is not required. If fast performance is required, it is better to consider the use of functions with memory-aligned conversion tables.
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) 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_hflipSpriteM1(6, 16, flagSprite); timesdrawn = 0; } // Draw the flag pvmem = cpct_getScreenPtr(CPCT_VMEM_START, x, y); cpct_drawSprite(flagSprite, pvmem, 6, 16); }
AF, BC, DE, HL
C-bindings | 86 bytes |
ASM-bindings | 83 bytes |
Case | microSecs (us) | CPU Cycles | ----------------------------------------------------------------------- Even-width | (48WW + 16)H + 32 | (192WW + 64)H + 128 | Oven-width | (48WW + 36)H + 37 | (192WW + 144)H + 148 | ----------------------------------------------------------------------- W=2,H=16 | 1056 | 4224 | W=5,H=32 | 4261 | 17044 | ----------------------------------------------------------------------- Asm saving | -12 | -48 | -----------------------------------------------------------------------
WW = width/2, H = height