ScreenFX module API 21-Jul-2007
=================== ===========
[NOTE: If you update this documentation, be sure to update ScreenFX.h too.]
The ScreenFX module programs palette brightness and supremacy values to
perform various effects such as fading the screen brightness between normal
and black, or fading the graphics plane in and out of visibility over a
video plane.
* SWI calls
---------
SWI ScreenFX_Fade
(SWI &0x58440)
Smoothly fade red, green, blue and supremacy values.
On entry
R0 = Flags:
Bit Meaning
0 If set, block while fading, else fade in background
1 If set, don't trigger callbacks when doing a blocking fade
(else, callbacks will trigger roughly after each VSync)
3 If set, allow Escape to cancel blocking fades just as if
ScreenFX_Cancel were called; else Escape is ignored (note
use of bit 3, not bit 2)
Other bits are reserved and must be set to zero.
R1 = Fade left hand end point, 32-bit, &BBGGRRSS
R2 = Fade right hand end point, 32-bit, &BBGGRRSS
R3 = Duration of fade in centiseconds
On exit
All registers preserved unless R0:3 set on entry, in which case:
R0 = Flags:
Bit Meaning
3 If set, operation ended early due to an escape condition.
If clear, operation completed normally.
Other bits are reserved and must be ignored.
All other registers preserved
Flags are corrupted
Interrupts
Interrupt status is not altered
Processor mode
Processor is in SVC mode
Re-entrancy
SWI is not re-entrant
Use
RISC OS supports mappings for the brightness levels of each of the three
colour components of red, green and blue. In a 32bpp screen mode or when
setting up a user defined palette, 256 shades of red, green and blue are
available. The actual brightness that these shades show on the screen is
programmable. Normally, the mapping is simple - a value of zero leads to
zero brightness, whilst a value of 255 leads to full brightness, with a
linear distribution of values in between. So, RISC OS uses four tables of
256 values to describe the brightness of red, green and blue, and the
supremacy of the whole graphics plane relative to an underlying video
plane. Note that with supremacy, a value of 0 indicates that the graphics
plane is opaque and 255 means that it is fully transparent.
The ScreenFX_Fade SWI call implements a smooth fade between whatever the
current R, G, B and S tables are, to a new final set of values for the R,
G, B and S tables. It allows you to specify the left and right hand end
points of a straight line graph describing displayed intensity for each
of the four channels. For example, if we consider the red channel alone
as a table with 256 entries, the lowest entry is usually set to a
brightness level of 0, whilst the highest entry is usually set to 255 for
full brightness, with a linear spread of values between. In this case the
"left hand end point" value is the zero and the "right hand end point" is
255. We could thus invert the red channel by reversing the end point
values - specify a left hand end point of 255 and a right hand end point
of zero. We could alternatively make all red values the same intensity by
setting the left and right hand end points to the same value.
The value of R1 on entry gives the left hand end point for each of the
four channels packed into a 32-bit word. R2 gives the right hand end
point and R3 gives the overall duration of the fade in centiseconds.
Fading is implemented on VSync events, so the number of steps actually
shown to get from the current screen setting to the target screen setting
in the given time depends on both the duration of the fade and the
refresh rate of the current screen mode.
Normally, fades run in the background on VSync events. To block during a
fade, set R0:0 on entry. The SWI call will not return until the fade has
completed. Callbacks will normally be triggered after VSyncs when waiting
for a blocking fade to complete, unless R0:1 is set. During a blocking
fade the Escape key is normally disabled. To allow it to cancel the fade
just as if SWI ScreenFX_Cancel had been called, set R0:3 on entry. The
escape key is explicitly enabled with OS_Byte 229 for the duration of the
fade. The old escape state is restored afterwards.
If a fade is already in progress when a new fade is requested, the old
fade is cancelled. The new fade will continue where the old fade left
off. The duration will be a percentage of the value given in R3, based on
the remaining percentage of time that the old fade had been running. For
example, if an old fade was 40% complete, the new fade will last for 40%
of the value given in R3. This is based around the idea that fades go
from current settings to a target, and that most common interruptions
will be when a fade in one direction is followed by a fade reverting to
the original settings shortly after; the length of time this should take
depends on the "distance" the second fade has to go, which is greater if
the first fade had almost completed, or short if the first fade had only
just started.
To program an absolute setting quickly, set R3 to zero on entry. The
change will occur on the next VSync. Doing this also aborts any existing
fade activity. To cancel any in progress fade without changing whatever
RGBS values it had reached, use SWI ScreenFX_Cancel.
Related SWIs
ScreenFX_Cancel
Related vectors
None
SWI ScreenFX_Cancel
(SWI &0x58441)
Cancel a fade operation.
On entry
R0 = Flags (reserved, set to zero)
On exit
All registers preserved
Flags are corrupted
Interrupts
Interrupt status is not altered
Processor mode
Processor is in SVC mode
Re-entrancy
SWI is not re-entrant
Use
This SWI call abandons any operation started with SWI ScreenFX_Fade.
R, G, B values and supremacy levels are left at the values to which they
had most recently been programmed.
The SWI does nothing if there is no fade in progress when it is called.
Related SWIs
ScreenFX_Fade
Related vectors
None
SWI ScreenFX_Reset
(SWI &0x58442)
Cancel a fade operation and reset to default screen settings.
On entry
R0 = Flags (reserved, set to zero)
On exit
All registers preserved
Flags are corrupted
Interrupts
Interrupt status is not altered
Processor mode
Processor is in SVC mode
Re-entrancy
SWI is not re-entrant
Use
This SWI internally calls ScreenFX_Cancel then programs the screen
gamma and supremacy with the default linear tables, holding value
0 at index 0 through to value 255 at index 255.
Related SWIs
ScreenFX_Fade
Related vectors
None
SWI ScreenFX_Status
(SWI &0x58443)
Read the current ScreenFX module status.
On entry
R0 = Flags (reserved, set to zero)
On exit
R0 = Activity flags:
Bit Meaning
0 If set, a ScreenFX_Fade operation is in progress in the
background.
1 If set, a ScreenFX_CrossFade operation is in progress in the
background.
Other bits are reserved and must be ignored.
R1 = Current left hand end point, 32-bit, &BBGGRRSS
R2 = Current right hand end point, 32-bit, &BBGGRRSS
R3 = Remaining time for the current operation if one is in progress,
else zero
R4 = Pointer to the R-G-B-S tables for the current values
Other registers are preserved
Flags are corrupted
Interrupts
Interrupt status is not altered
Processor mode
Processor is in SVC mode
Re-entrancy
SWI is not re-entrant
Use
This call reports the current status of the screen display and indicates
whether or not a fade operation is in progress.
Since RISC OS provides no way to read the current programmed hardware
values, the ScreenFX module will always assume linear tables from 0 to
255 when it starts, and maintain the notion of current settings based on
an internal soft copy thereafter.
The values on exit provided in R1 and R2 have the same meaning as those
supplied on entry to SWI ScreenFX_Fade. In addition, a pointer to the
base of the RGBS tables is provided in R4. Each table consists of 256
8-bit entries, with each table appearing in memory directly after any
previous table, in the order of red, green, blue and supremacy. The whole
table pointed to by R4 is therefore 1024 bytes long, as four sets of 256
byte long entries. The first entry of each table corresponds to a value
written into screen memory in 32bpp of zero for that channel and the last
entry corresponds to a value in screen memory of 255 for that channel.
Related SWIs
ScreenFX_Fade
Related vectors
None
SWI ScreenFX_CrossFade
(SWI &0x58444)
Smoothly fade red, green and blue values to achieve a visual cross-fade
between two images dithered into one screen bank.
On entry
R0 = Flags:
Bit Meaning
0 If set, block while fading, else fade in background
1 If set, don't trigger callbacks when doing a blocking fade,
else callbacks will trigger roughly after each VSync
2 If set, fade to the low half of each colour component,
else, fade to the high half of each colour component
3 If set, allow Escape to cancel blocking fades just as if
ScreenFX_Cancel were called; else Escape is ignored
Other bits are reserved and must be ignored.
R1 = Duration of fade in centiseconds
On exit
All registers preserved unless R0:3 set on entry, in which case:
R0 = Flags:
Bit Meaning
3 If set, operation ended early due to an escape condition.
If clear, operation completed normally.
Other bits are reserved and must be ignored.
All other registers preserved
Flags are corrupted
Interrupts
Interrupt status is not altered
Processor mode
Processor is in SVC mode
Re-entrancy
SWI is not re-entrant
Use
In ScreenFX, a cross-fade is defined as the ability to fade
between having one image visible and another image visible, such
that during the fade both images will be simultaneously seen on
screen in varying proportions as the fade progresses.
Cross-fading between two images may be accomplished by having a
rendered copy of each image, then calculating on a pixel by pixel
basis a merged image to paint to the screen representing the
various stages of a fade from one image to the other. This takes
a great deal of CPU power and RAM bandwidth. An alternative
mechanism uses hardware graphics planes, having one image on a
plane "above" another image, then gradually making the top plane
transparent to reveal the other image. This uses much less CPU
power but requires specific hardware support for at least two
full screen graphics planes with translucency on at least one.
ScreenFX provides support for an unusual alternative that makes
use of the gamma tables supported by the Risc PC, Iyonix, and most
other RISC OS computers produced after the Risc PC. The easiest
example uses a 32bpp (16.7M colour) screen mode. In this mode,
each pixel is made up of 8-bit colour components for red, green
and blue, plus an 8-bit supremacy channel. Ignoring the latter, we
could consider the screen to contain, rather than one image of 8
bits per colour component, two images, each with 4 bits per colour
component. One image is painted into the upper 4 bits of each
colour component in screen RAM, whilst the other is painted into
the lower 4 bits. In effect, there are two images of 12bpp each,
occupying the 24bpp colour parts of a 32bpp screen mode.
Special drawing code is needed to produce such a display. At
the simplest level, it is very easy to paint two images into
the upper or lower 4 bits using a small piece of custom copy code
taking a 24bpp source, and not much harder to introduce simple
dithering to make the 12bpp result look better. ScreenFX does not
provide custom drawing routines; clients are responsible for
arranging the screen RAM contents appropriately before starting a
cross-fade operation.
Once the two 12bpp images are present in screen RAM, the user will
see the upper 4 bits image quite clearly, with the lower 4 bits
(assuming normal gamma table programming) appearing as a ghost
image on top. ScreenFX provides cross-fade functions where the
gamma tables get programmed to make the upper or lower 4 bits of
each colour component visible, occupying a full range of 16
brightness levels independently. By moving smoothly from one table
showing the upper 4 bits to another table showing the lower 4 bits
or vice versa, a smooth cross fade effect is achieved with no
special hardware support requirements and very low demand on the
host CPU. Control of whether the upper or lower bits of each
colour component are ultimately visible is controlled with flag
bit 2 of R0 on entry. The other flag bits of R0 are analogous to
the same bits in R0 on entry to SWI ScreenFX_Fade.
ScreenFX can program tables for 256, 32K or 16M colour modes. In
256 colours, it uses just one bit per colour component per image
giving only 8 colours in total for each, using only only 6 of the
8 bits per pixel available with each colour component given equal
weight. In 32K colour modes, of the 5 bits per colour component
available, only four are used; bits 0-1 for the 'low' image and
2-3 for the 'high' image. Bit 4 is ignored, giving 64 colours for
each image. The 16.7M colour mode operation is by far the most
simple, where ScreenFX uses 4 bits per colour component to give
4096 colours per image with no wastage.
In 256 colour modes, a linear greyscale palette (colour zero is
black, colour 255 is white) must be used to get a correct mapping
between pixel byte values and gamma table entries. Other palettes
can be programmed for unusual effects. ScreenFX does not alter
the palette itself. ScreenFX only supports 256, 32K and 16M colour
modes for crossfades - attempting to start a cross-fade in another
colour depth will result in error &81D900, "ScreenFX does not
support the requested operation in the current colour depth".
The success of the technique depends on screen resolution and the
quality of any dithering algorithms used. Certain material may be
specially constructed to only use the 8, 64 or 4096 colours
available, in which case the results should be excellent.
Cross-fading always occurs equally for R, G and B channels, and
since an unusual table is being set up, cross fading to or from a
normal gamma table from or to the high or low part of the colour
components will only be successful if the normal table contains
all zero values (black). It is generally best to program the gamma
tables for black, paint in the two images, then either cross fade
or do an instant setting to make one of the two images visible,
then cross fade to the other image and replace the first once the
second is fully visible ready for the next transition.
If a previous fade is interrupted, the new fade duration will be
scaled back according to the calculated "distance" to get from
the current gamma tables to the target tables, just as with SWI
ScreenFX_Fade.
Related SWIs
ScreenFX_Fade
ScreenFX_Cancel
Related vectors
None
* Star commands
-------------
ScreenFXFade
This is a command-line interface to SWI ScreenFX_Fade. Syntax:
*ScreenFXFade [-block]
The first parameter is an optional switch which if present sets bit 0 of
on entry to SWI ScreenFX_Fade. The next two mandatory parameters are the
32-bit RGBS values giving the destination R, G, B and transparency values
for the fade represented as 9 character entities with a mandatory leading
"&", each consisting of four pairs of two digit upper or lower case hex
values, or a decimal specifier (though it's usually much easier to use
hex!). The last parameter is a duration value in centiseconds.
ScreenFXCrossFade
A command line interface to SWI ScreenFX_CrossFade. Syntax:
*ScreenFXFade [-block] [-low]
The first parameter is an optional switch which if present sets bit 0 of
on entry to SWI ScreenFX_CrossFade. The next parameter sets bit 2 of R0
on entry if present, to fade to the low half of colour components. The
final parameter is the duration value in centiseconds.
ScreenFXCancel
This is a command-line interface to SWI ScreenFX_Cancel. Syntax:
*ScreenFXCancel
There are no parameters.
ScreenFXReset
This is a command-line interface to SWI ScreenFX_Reset. Syntax:
*ScreenFXReset
There are no parameters.
ScreenFXStatus
This is a command-line interface to SWI ScreenFX_Status. Syntax:
*ScreenFXStatus
There are no parameters. The precise output depends upon the Messages
file settings for the current locale, but is of the form:
ScreenFX 0.01 (18-Aug-2005) status:
RGBS left endpoint &BBGGRRSS
RGBS right endpoint &BBGGRRSS
Fade in progress 1 (Yes)
Time to completion 20cs
The ordering of items above is not expected to change, even if the
wording does; note the locale-independent use of a number as well as
a locale-dependent string for the "Fade in progress" indication.