cpct_hflipSpriteM0_r

Horizontally flips a sprite, encoded in screen pixel format, mode 0.  (ROM-friendly version).

C definition

void cpct_hflipSpriteM0_r (void* sprite, u8 width, u8 height) __z88dk_callee;

Input Parameters (4 bytes)

(2B DE) spritePointer to the sprite array (first byte of consecutive sprite data)
(1B L) widthWidth of the sprite in bytes (NOT in pixels!).  Must be >= 1.
(1B H) heightHeight of the sprite in pixels / bytes (both are the same).  Must be >= 1.

Assembly call (Input parameters on registers)

call cpct_hflipSpriteM0_r_asm

Parameter Restrictions

  • sprite must be an array containing sprite’s pixels data in screen pixel format (Mode 0 data).  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).  Warning!  This function will admit any 16-bits value as sprite pointer and will modify bytes at the given address.  On giving an incorrect address this function will yield undefined behaviour, probably making your program crash or doing odd things due to part of the memory being altered by this function.
  • 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 1 byte = 2 pixels (mode 0)
  • height must be the height of the sprite in pixels / bytes (both should be the same amount), and must be greater than 0.  There is no practical upper limit to this value, but giving a height greater than the height of the sprite will yield undefined behaviour, as bytes after the sprite array might result modified.

Known limitations

  • This function does not do any kind of boundary check.  If you give it incorrect values for width, height or sprite pointer it might potentially alter the contents of memory locations beyond sprite boundaries.  This could cause your program to behave erratically, hang or crash.  Always take the necessary steps to guarantee that your values are correct.
  • As this function receives a byte-pointer to memory, it can only flip 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.

Details

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_r(sprite, 4, 4);

// 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.

Use example

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_r(characterSprite, 4, 8);
      wasLookingAt = lookingAt;
   }

   // Draw main character's sprite
   pvmem = cpct_getScreenPtr(CPCT_VMEM_START, x, y);
   cpct_drawSprite(characterSprite, pvmem, 4, 8);
}

Destroyed Register values

AF, BC, DE, HL

Required memory

C-bindings48 bytes
ASM-bindings45 bytes

Time Measures

 Case       |      microSecs (us)       |         CPU Cycles          |
-----------------------------------------------------------------------
 Even-Width |     (37WW + 24)H + 14     |      (148WW +  96)H + 56    |
  Odd-Width |     (37WW + 46)H + 14     |      (148WW + 184)H + 56    |
-----------------------------------------------------------------------
 W=2,H=16   |           990             |           3960              |
 W=5,H=32   |          3854             |          15416              |
-----------------------------------------------------------------------
 Asm saving |          -12              |            -48              |
-----------------------------------------------------------------------

WW = width/2, H = height

Horizontally flips a sprite, encoded in screen pixel format, mode 0.
unsigned char (u8 = unsigned 8-bits, 1 byte )
Transforms 2 pixel colour values [0-15] into a byte value in the video memory pixel format for Mode 0.
Close