Horizontally flips a sprite, encoded in screen pixel format, mode 0.
void cpct_hflipSpriteM0 (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_hflipSpriteM0_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 0), like in this example:
// Example call. Sprite has 8x4 pixels (4x4 bytes) cpct_hflipSpriteM0(4, 4, sprite); // Operation performed by the call and results // // -------------------------------------------------------------- // | Received as parameter | Result after flipping | // -------------------------------------------------------------- // | sprite => [05][21][73][40] | sprite => [04][37][12][05] | // | [52][23][37][74] | [47][73][32][25] | // | [05][11][31][04] | [04][13][11][50] | // | [00][55][44][00] | [00][44][55][00] | // -------------------------------------------------------------- // Sprite takes 16 consecutive bytes in memory (4 rows with 4 bytes) //
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 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_hflipSpriteM0(4, 8, characterSprite); wasLookingAt = lookingAt; } // Draw main character's sprite pvmem = cpct_getScreenPtr(CPCT_VMEM_START, x, y); cpct_drawSprite(characterSprite, pvmem, 4, 8); }
AF, BC, DE, HL
C-bindings | 68 bytes |
ASM-bindings | 65 bytes |
Case | microSecs (us) | CPU Cycles | ----------------------------------------------------------------------- Even-width | (32WW + 16)H + 32 | (128WW + 64)H + 128 | Oven-width | (32WW + 36)H + 37 | (128WW + 144)H + 148 | ----------------------------------------------------------------------- W=2,H=16 | 800 | 3200 | W=5,H=32 | 3237 | 12948 | ----------------------------------------------------------------------- Asm saving | -12 | -48 | -----------------------------------------------------------------------
W = width % 2, WW = width/2, H = height