Showing changes from revision #2 to #3:
Added | Removed | Changed
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> <right> <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.