New Calls

        OS_SpriteOp codes 35-36, 50-53, 60-61
                SpriteReason_AppendSprite
                SpriteReason_SetPointerShape
                SpriteReason_PlotMaskScaled
                SpriteReason_PaintCharScaled
                SpriteReason_PutSpriteScaled
                SpriteReason_PutSpriteGreyScaled
                SpriteReason_SwitchOutputToSprite
                SpriteReason_SwitchOutputToMask
        OS_ReadVduBlockSize

Introduction

The Arthur sprite extension module is available as an upgrade to the Arthur 1.20 operating system, providing some extra reason codes to SWI OS_SpriteOp. The module is provided as standard in the Arthur 2.00 ROM, and the kernel also supports calls to redirect VDU output into sprites.

The extra sprite operations allow arbitrary scaling and colour translation: they are used by the Wimp to implement mode-independence, and by bit-mapped printer drivers to cope with the fact that printers have a different pixel resolution from the screen.

Installation

To install the sprite extension module, simply *RMLoad it (if it is held in the library, then *SprExtend will do.


Due to the way in which the sprite vector is intercepted, the sprite extension module must be loaded before the printer driver (if any).

The SWI interface

As with all sprite operations, the extra operations implemented in the sprite extension module are accessed via SWI OS_SpriteOp. The extra reason codes are:

        35      AppendSprite
        36      SetPointerShape
        50      PlotMaskScaled
        51      PaintCharScaled
        52      PutSpriteScaled
        53      PutSpriteGreyScaled
        60      SwitchOutputToSprite
        61      SwitchOutputToMask

A short explanation of what the operations do is given below:

35 AppendSprite

Entry: R0 = reason code
R1 = areaCBptr
R2 = name/ptr of 1st sprite
R3 = name/ptr of 2nd sprite
R4 = flags (0 ==> merge horizontally, else vertically)
Exit: 1st sprite is result of merging both
2nd sprite is deleted
        scratch space used (no extra memory apart from that)

This call can be used to merge two sprites into one, tacking them together vertically or horizontally. It does not use any extra memory, so is useful if memory is tight!

36 SetPointerShape

Entry: R1 --> sprite area
R2 --> sprite name/address
R3 bits 0..3 = pointer shape number (1..4)
R3 bit 4 set => don't bother to set the pointer shape data
R3 bit 5 set => don't bother to set the palette from the sprite
R3 bit 6 set => don't bother to program the pointer shape number
R4,R5 = coordinates of active point (pixels from top-left)
R6 --> factors
R6 <= 0 ==> use default, depending on screen mode
R7 --> pixel translation table (target = 2 bpp)
R7 <= 0 ==> no translation
(See 'PutSpriteScaled' below for a description
                of the format of a pixel translation table)

This call allows any of the hardware pointer shapes to be programmed from a sprite, with some degree of mode-independence (ie. the aspect ratio is catered for).

Note that in hi-res mono modes, the pointer shape resolution is 4 times worse horizontally than the pixel resolution, and that only colours 0, 1 and 3 can be used in the pointer shape definition. The SpriteExtend call caters for the resolution problem by halving the width of the pointer, so that it is still possible to see what it is, although the pointer will be twice as wide as usual.

Bits 4, 5 and 6 of R3 can be used to defer certain aspects of this call until later: for example, if one wanted to set up the pointer shape data without
displaying the pointer, one could set bits 5 and 6 to avoid programming the palette and pointer shape number.

Note that if the sprite is given a translation table, SpriteExtend will search the table to find out which colours were mapped onto colours 1, 2 and 3 in the pointer, and will set the palette entries from those colours.

If the sprite has no palette, the palette setting code is not done, and no error is reported.

50 PlotMaskScaled

Entry: R0 = &132 or &232 (as appropriate)
R1 = areaCBptr
R2 --> sprite name / sprite header (depends on R0)
R3,R4 = coords to plot sprite at
R6 --> scale factors (x-mag, y-mag, x-div, y-div)
        R6 <= 0 ==> no scaling

An area of the screen corresponding to the 'solid' pixels in the sprite mask (scaled appropriately) is painted using the current graphics background colour and action. If this is an ecf pattern, the pattern is not scaled up.

51 PaintCharScaled

Entry: R0 = &133 or &233
R1 = character code
R3,R4 = coords to paint character at
        R6 --> scale factors (x-mag, y-mag, x-div, y-div)

The specified character is painted on the screen with its lower-left corner at the coordinate specified in R3,R4, using the current graphics foreground colour and action.

52 PutSpriteScaled

Entry: R0 = &134 or &234
R1 = areaCBptr
R2 --> sprite name/header
R3,R4 = coords to plot sprite at
R5 = gcol action
R6 --> scale factors (x-mag, y-mag, x-div, y-div)
R6 <= 0 ==> no scaling
R7 --> pixel translation table (byte array)
        R7 <= 0 ==> no translation

The sprite is plotted at the coordinate specified in R3,R4 using the gcol action in R5, scaled by the factors pointed to by R6 and the pixels transated using the table pointed to by R7.

If bit 3 of R5 is set, then the sprite's mask is used, otherwise not.

If R6>0 then the sprite is scaled by the specified amount, otherwise it is not scaled (ie. the scaling is taken to be 1:1).

If R7>0 then the pixels are translated according to the byte array pointed to by R7. This table allows the sprite to be plotted (for instance) in a mode with a different number of bits per pixel than that for the mode in which the sprite is defined. In 256-colour modes, the format of the pixels is taken to be that which relates to the actual screen, rather than the colour/tint values used for GCOL n,c. Note that the error 'Bad translation table' is returned if the translation supplied (or not supplied) means that the output pixel values are too big for the number of bits per output pixel.

53 PutSpriteGreyScaled

Entry: R0 = &135 or &235
R1 = areaCBptr
R2 --> sprite name/header
R3,R4 = coords to plot sprite at
R5 = gcol action (not implemented - 0 assumed)
R6 --> scale factors (x-mag, y-mag, x-div, y-div)
R6 <= 0 ==> no scaling
R7 --> pixel translation table
        R7 <= 0 ==> no translation

This operation is similar to PutSpriteScaled, except that it performs anti-aliasing on the sprite as it scales it, in the same way as the Font Manager scales its character definitions. This means that the sprite used must have been defined in a mode with 4 bits per pixel, and the pixels must reflect a linear grey scale (as with anti-aliased font definitions).

PutSpriteGreyScaled is considerably slower than PutSpriteScaled, and should only really be used when the quality of the image is of the utmost importance. To speed up the redrawing of an anti-aliased image, it is possible to draw the image into another sprite (using the Arthur 2.00 SwitchOutputToSprite call), which can then be redrawn more rapidly.

The OS_SpriteOp calls 60, 61 and 62 are implemented in the Arthur 2.00 kernel and are documented in "VDU output to sprites/1"