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] <left &BBGGRRSS> <right &BBGGRRSS> <duration>

  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] <duration>

  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.
