cpct_hflipSpriteM1

Horizontally flips a sprite, encoded in screen pixel format, mode 1.

C definition

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

Input Parameters (4 bytes)

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

Assembly call (Input parameters on registers)

call cpct_hflipSpriteM1_asm

Parameter Restrictions

  • sprite must be an array containing sprite’s pixels data in screen pixel format (Mode 1 data, 4 pixels per byte).  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 1 (cpct_px2byteM1).  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 = 4 pixels (mode 1)
  • 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 will not work from ROM, as it uses self-modifying code.
  • 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 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.

Use example

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);
}

Destroyed Register values

AF, BC, DE, HL

Required memory

C-bindings86 bytes
ASM-bindings83 bytes

Time Measures

 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

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