Showing changes from revision #4 to #5:
Added | Removed | Changed
Entry | |
---|---|
R0 | 38 (Reason code) + Area value |
R1 | Unused/Sprite area (as defined by area value in R0) |
R2 | Sprite name/pointer (as defined by area value in R0) |
R3 | Flags: |
Bits 0-7: Cutoff value when reducing to 1bpp | |
Bit 8: Remove mask completely if possible | |
Bits 30-31: Operation: | |
0 = Convert to 1bpp mask | |
1 = Reserved | |
2 = Convert to 8bpp alpha mask | |
3 = Convert to alpha channel |
Exit | |
---|---|
R3 | If the call failed due to lack of space in the sprite area, R3 is the amount of extra space required |
In all other cases, R3 is zero | |
All other registers preserved |
This call allows the mask or alpha data of a sprite to be converted between the four different types:
When a sprite is being converted to a 1bpp alpha mask/alpha channel, bits 0-7 of R3 are used as a cutoff value to decide whether mask pixels should be 0 or 1. If the source mask/alpha value (once expanded to 8 bits) is greater than or equal to the cutoff value, a value of 1 will be written, else a value of 0.
When the number of bits in the mask/alpha is being reduced (8bpp to 4bpp, 8bpp to 1bpp, or 4bpp to 1bpp), setting bits 0-7 of R3 to zero will prevent the conversion from being performed if it will result in the loss of data. For a 1bpp destination this means that the conversion will only occur if the source mask/alpha is a simple binary mask (i.e. 8bpp mask pixels are only 0 or 255). For a 4bpp destination this means that the conversion will only occur if the top and bottom nibbles of the 8bpp source data match (i.e. there are only 16 levels of transparency &00, &11, &22, &33, etc.)
If bit 8 of R3 is set then the mask/alpha channel will be removed if it is redundant; i.e. if all pixels have an alpha of 255. This redundancy checking is performed with respect to the destination alpha/mask format. This means that, for example, when converting an 8bpp mask to 1bpp, if all pixels are above the cutoff value and bit 8 is set then the mask will be discarded.
Note that for compatibility with RISC OS Select, bits 0-8 are ignored for operation 2. For bits 0-7 this doesn’t matter (as the mask is never losing precision), but for bit 8 it means there’s no way of removing a redundant alpha mask. See the examples below for a workaround1
If the call fails due to lack of space in the sprite area, it will exit with V set, R0 pointing at an error block (error &85, “SpriteExtend: Not enough memory for sprite operation”), and with R3 containing the amount the sprite area must be grown by in order for the call to succeed. If the call completes successfully, or fails with any other error, R3 will be zero.
To convert a sprite to a 1bpp mask, but only if the existing mask/alpha data is binary, use a flags word of &100
To convert a sprite to a 1bpp mask, with a cutoff value of 50%, and to discard the mask where possible, use a flags word of &180
To convert a sprite to a RISC OS Select-compatible 8bpp alpha mask, or to create an empty alpha mask, use a flags word of &80000000
To convert a sprite to a RISC OS 5-compatible alpha channel, with a cutoff value of 50% when converting to 1bpp alpha from an 8bpp alpha mask, use a flags word of &c0000080
1 Discarding redundant alpha masks
If you use a flags word of &C0000100 then an attempt will be made to convert the mask to an alpha channel, without losing any precision, and discarding it if it is irrelevant. The determination of which alpha format to use is made after an initial check for redundancy, so this call will successfully remove redundant alpha masks even when used on sprites where an alpha channel is impossible (e.g. palletised palettised sprites).
Once the conversion is complete, use OS_ReadModeVariable to read the Mode Flags of the Sprite Mode Word. If the flags indicate RGB colour space with the alpha flag set, call OS_SpriteOp 38 again, but with a flags word of &80000000. This will convert the alpha channel back to an alpha mask. For other mode flag combinations no action should be necessary, as it either means the mask was redundant (and removed) or non-redundant (but impossible to remove due to an alpha channel being impossible to add).
This call only supports sprites which have a RISC OS 3.5 or RISC OS 5 style sprite mode word. Attempting to use it on a sprite with an old-style mode word (i.e. where the mode word is just a mode number) will result in an error.
Where possible, the sprite mode word will be transformed into its most backwards-compatible form. This includes removing the alpha mask flag if the sprite doesn’t have an alpha mask, and attempting to convert any RISC OS 5 sprite mode word to its equivalent RISC OS 3.5 form. This mode word conversion will take place even if the mask/alpha data is not being modified by a particular call.
Conversion to an alpha channel is only possible for sprite types 5 (32K colours), 6 (16M colours at 32bpp), and 16 (4K colours).