www.riscos.com Technical Support: |
|
A sprite is an area of memory that can be treated like a small block of screen memory. It contains a graphic shape made up of an array of pixels.
A sprite has the following attributes:
If the sprite has a transparency mask, you can cause certain pixels in the sprite not to be written to the existing screen display. By using this mask, you can effectively make a sprite any shape.
A sprite can be defined by grabbing some or all of the screen, or defining it a pixel at a time or by making the VDU plot operations go into a sprite instead of the screen memory.
Once defined, a sprite can be manipulated in many ways, such as having rows and columns inserted or deleted, flipping it about the x or y axis and changing the colour of particular pixels.
A sprite can be plotted onto the screen scaled to any size, or transformed, and its colours can be altered using a lookup table.
Sprites are stored in sprite files, which may contain one or more sprites with different names.
RISC OS can use sprites from the system sprite area, from the Wimp's common sprite pool, or from any number of user sprite areas.
The system sprite area is defined by the kernel. Its size can be controlled by a slider in the task manager application on the desktop.
This area is public and can be accessed from any program or module, so is a convenient place to experiment using sprites. However, you should not use the system sprite area in commercial applications and should instead use a combination of the Wimp's common sprite pool and user sprite area as appropriate.
Note that the Sprite module * Commands only work with sprites in the system sprite area.
Alternatively, an application or a module may reserve its own space. This is private space, which can only be used by the application or module that reserved it. For example, the Wimp has a shared sprite pool, which is passed to OS_SpriteOp as a user area.
Unlike the system area, there can be several user areas which are referenced via pointers to the start of the areas. In user areas, as well as being able to refer to a sprite by name, you can also refer to it by address. This plainly will be much faster, since there is no overhead to search through the available names.
With the sprite module, it is possible to issue calls to:
Sprites can be loaded and saved to any valid pathname. The simplest way of doing this is to use the calls to load or save the current graphics window as a single sprite file.
For more sophisticated control, a sprite area (system or user) can be saved, or loaded. It is also possible to merge a sprite file with what is already in memory.
You can create a blank sprite of a specified height and width. Subsequently, individual pixels can be changed within it.
You also have various ways of grabbing some or all of the graphics window and putting it into a sprite.
The various sprite editing utilities all use one or other of these techniques.
If you try to create a sprite with a palette, the palette is incorrect if it is for a different number of bits per pixel to that used by the current mode. The best workround is to create the sprite without a palette, and then to add the palette.
The mask can be enabled and disabled as required. Like a sprite, it can have individual pixels set or cleared. A sprite may have up to 256 colours, depending on which mode it was created in; the mask pixels are either on (solid), in which case the pixel colour is used, or off (transparent), in which case it is not plotted.
The other way of writing to a sprite or its mask is to redirect the VDU operations to a sprite. This means that the sprite rectangle is treated like a graphics window, putting data into the sprite in the same format as the screen memory.
There are several ways of plotting a sprite into the screen memory. There is a SWI that will simply plot the sprite. You can also plot it using the mask if one is attached to it. The scale of the sprite can be changed to be any desired size. Thus, zooming into a sprite is made very easy.
The anti-aliasing technique used by the font manager with characters can be used here with sprites. A range of close colours are used to shade the sprite, which can be plotted with or without a mask, and scaled to any size.
The format of a sprite area is as follows:
The sprite area control block contains the following:
Bytes | Contents |
---|---|
0 - 3 | Byte offset to last byte+1 (ie total size of sprite area) |
4 - 7 | Number of sprites in area |
8 - 11 | Byte offset to first sprite |
12 - 15 | Byte offset to first free word (ie byte after last sprite) |
16... | Extension words (usually null) |
The above offsets are relative to the start of the sprite area control block.
The format of the file created by a *ScreenSave or *SSave command is the same as a sprite area, save that word 1 of the control block is not saved. (There is no need to save this, as the total size of the sprite area is the size of the file).
The format of a sprite is as follows:
The Sprite Control Block contains the following:
Bytes | Content |
---|---|
0 - 3 | Offset to next sprite |
4 - 15 | Sprite name, up to 12 characters with trailing zeroes |
16 - 19 | Width in words -1 |
20 - 23 | Height in scan lines -1 |
24 - 27 | First bit used (left end of row) |
28 - 31 | Last bit used (right end of row) |
32 - 35 | Offset to sprite image |
36 - 39 | Offset to transparency mask or offset to sprite image if no |
mask | |
40 - 43 | Mode sprite was defined in (see Sprite modes) |
44... | Palette data (optional) |
The size of the palette data block depends on the number of bits per pixel in the sprite's mode, since there will be one entry for each potential logical colour.
Each entry is two words long. These are the words returned from OS_ReadPalette. The format of these words is described with this SWI on OS_ReadPalette.
256 colour modes may be an exception to this rule, because there are only 16 palette registers in VIDC. Most 256 colour sprites will have 16 palette entries; those created by *ScreenSave actually have 64 palette entries; some generated by programs will have a full 256 palette entries. The standard RISC OS display routines pass the last 16 entries to VIDC. For notes on using sprites with 256 entry palettes, see the chapter entitled Using sprites with 256 entry palettes.
The format of a sprite image is as follows:
The image contains the rows of the sprite from top to bottom, all word-aligned. Each pixel is a group of bytes per character bits (see OS_ReadVduVariables on OS_ReadVduVariables). The least significant pixel in a word is the left-most one on the screen.
Note that in the diagram above, bit 0 of each word has been shown on the left, and bit 31 has been shown on the right; this is to clarify how wastage occurs. Note also that there will not necessarily be 4 pixels per word.
A sprite mask is the same size as the corresponding sprite image, and the same bits refer to each pixel. In the mask, the bits of each pixel must either all be set (the sprite's pixel is solid) or all be cleared (the pixel is transparent).
Several kinds of parameter are used by many SWIs within the sprite module. Rather than repeating their definitions each time, they are described here.
Many of the sprite SWIs use a pointer to control block of sprite area parameter in R1 or that and a sprite pointer in R2. When either of these appear, then bits 8 and 9 in R0 control how these two registers are interpreted.
R0 bit 8 & 9 values | R1 effect | R2 effect |
---|---|---|
00 (+0) | not used | pointer to sprite name (system sprite area used) |
01 (+256) | pointer to user sprite area | pointer to sprite name |
10 (+512) | pointer to user sprite area | pointer to sprite |
11 (+768) is invalid |
Note that the sprite names are null terminated.
For example OS_SpriteOp 256+33,CBlock,NamePtr will interpret CBlock as a pointer to the user sprite area and use NamePtr as a pointer to the name of the sprite to use within that area.
Using a pointer to a sprite in the user area (R0+512) is the quickest way of using sprites, because the string lookup doesn't need to be done. Note however that direct pointers to sprites in a given area will become invalid if any sprite in that area changes size or is replaced.
To make your sprites readable by old releases of RISC OS, we recommend you use the following mode numbers in a sprite (see the chapter entitled Format of a sprite):
2 colours | 4 colours | 16 colours | 256 colours | |
---|---|---|---|---|
2 × 4 OS unit pixels | 0 | 8 | 12 | 15 |
4 × 4 OS unit pixels | 4 | 1 | 9 | 13 |
2 × 2 OS unit pixels | 18 | 19 | 20 | 21 |
The scale factor will change the size of a sprite. It is a pointer to a block of four words with the following elements:
Offset | Meaning |
---|---|
0 | x multiplier |
4 | y multiplier |
8 | x divisor |
12 | y divisor |
The size of the specified sprite on the screen when it has been plotted in pixels (not OS units), is multiplied by the multiplier and divided by the divisor, ie:
x pixel size = x start size (in pixels) × x multiplier / x divisor
y pixel size = y start size (in pixels) × y multiplier / y divisor
If the plot action is using an ECF pattern, then the pattern will not be scaled up with the sprite. This is so that the patterning will be correct when used with a large scale factor. See the chapter entitled ECF patterns for a description of ECF patterns.
If the pointer is zero, then no scaling is performed; ie 1:1 scale.
The Wimp uses a similar system to provide mode independence. For details see Wimp_ReadPixTrans on Wimp_ReadPixTrans.
This allows a logical colour to be substituted for each colour in the sprite. It is a pointer to a table of bytes. The number of bytes in the table depends on the number of colours in the mode in which the sprite was created.
A pixel of colour n in the sprite will be translated to the nth entry in the pixel translation table. The first entry in the table is at offset 0 (ie the 0th colour). So colour 3 in a pixel will get the value 3 bytes into the table and use that as its logical colour.
If the pointer is zero, then the colours in the sprite will be used. However, if the destination bits per pixel is less than the source bits per pixel, you will get an error.
The Wimp uses a similar system to provide mode independence. For details see Wimp_SetPalette, Wimp_ReadPalette, and Wimp_SetColour from Wimp_SetPalette onwards.
The ColourTrans module provides facilities for translation table calculations. For more information refer to the ColourTrans.
Note: A number of calls that use a pixel translation table specify it as optional. You can only omit it if the sprite you are plotting has the same number of bits per pixel as the current screen mode. We recommend you always supply a table, and leave it to RISC OS to ignore it if it is unnecessary.
The plot action is the way in which pixels are plotted onto the screen. Some SWIs use the VDU 18 setting, and others can be passed the number directly. In either case, the format is the same, apart from bit 3 (&08)
Value | Action |
---|---|
0 | Overwrite colour on screen with sprite pixel colour |
1 | OR colour on screen with sprite pixel colour |
2 | AND colour on screen with sprite pixel colour |
3 | exclusive OR colour on screen with sprite pixel colour |
4 | Invert colour on screen |
5 | Leave colour on screen unchanged |
6 | AND colour on screen with NOT of sprite pixel colour |
7 | OR colour on screen with NOT of sprite pixel colour |
&08 | If set, then use the mask; otherwise don't |
When you switch output to a sprite or its mask using OS_SpriteOp 60 or OS_SpriteOp 61, you can save the VDU context in a save area. The save area you pass is where the state that has just been entered will be saved if another redirection of VDU output is made.
The save area is a block of memory, the required size of which you can obtain by calling OS_SpriteOp 62. You cannot directly manipulate the contents, but for your reference the save area stores:
Mode variables are reconstituted from the sprite mode number or the display mode number as appropriate.
The kernel maintains a system save area for the screen. Therefore, if you swap output to a sprite, perform some operations and swap back, it will not be necessary to allocate a save area.
When you first switch output to a sprite or mask your save area must have a zero in the first word; it is therefore ignored, and the VDU state set to the default for the mode in which the sprite is defined. When you switch output away from the sprite or mask, RISC OS saves the VDU state to the save area, setting the first word to a non-zero value. Hence when that save area is next passed to OS_SpriteOp 60 or 61, RISC OS recognises that it contains a VDU state and restores it.
The use of save areas allows the VDU 'context' to be switched between various destinations, so that each area has its own separate VDU state.
Here are a couple of examples highlighting the above points. The first example shows how to set-up a once-off drawing into a sprite:
SYS "OS_SpriteOp",256+60,myarea,mysprite$,0 TO r0,r1,r2,r3 REM we don't need a save area, because nobody can swap output away from REM our sprite; and we won't want to restore the state we're in when REM we've finished our work on the sprite. ... do whatever graphics we want ... SYS "OS_SpriteOp",r0,r1,r2,r3 REM whatever output state was in force on entry is now restored
The second example shows how to draw into a sprite, interact with the user, while maintaining ECF patterns etc:
SYS "OS_SpriteOp",256+62,myarea,mysprite$ TO ,,,size DIM sarea size sarea!0=0 : REM mark as unset REPEAT SYS"OS_SpriteOp",256+60,myarea,mysprite$,sarea TO r0,r1,r2,r3 ... work on the sprite ... SYS "OS_SpriteOp",r0,r1,r2,r3: REM return to previous output REM at this point, our save area has been filled with our state; REM the next time we switch output to our sprite the OS variables REM will therefore be reset from it. ... talk to the user ... UNTIL bored
To initialise the system sprite area, you can call OS_SpriteOp 9 (*OS_SpriteOp 9) or *SNew. To change the system sprite area size, you can call OS_ChangeDynamicArea; you can also change the configured size of this area (which is used on a hard reset) by calling *Configure SpriteSize, or - except under RISC OS 2 - by using the Configure application.
In order to setup a user sprite area, you must first allocate space for it using the usual memory allocation calls. You must then set up the header for the area before you call OS_SpriteOp 9 to initialise it as a sprite area.
To check the state of a sprite area, *SInfo or OS_SpriteOp 8 will tell you how large the area is, how much has been used and how many sprites are in it. *SInfo will, of course, only work with the system area.
*SList will list the names of all sprites in the system area. OS_SpriteOp 13 allows you to find the name of a sprite given its number in the list. You would call OS_SpriteOp 8 first to find out how many sprites there are and then use this call to get the names one at a time.
The simplest sprite file operations are screen save and load. The screen save will take the entire graphics window and convert it into a sprite file. *ScreenSave and OS_SpriteOp 2 will perform this operation. *ScreenLoad and OS_SpriteOp 3 will load it back again, aligned with the bottom left hand corner of the current graphics window.
There is also a set of operations based around loading and saving sprite areas to a file. *SLoad and OS_SpriteOp 10 will load a sprite file into an initialised sprite area and set up all the pointers within it. To save, *SSave and OS_SpriteOp 12 will create a sprite file and write all the sprites from the specified sprite area into it.
The sprite load operations will delete all sprites currently in memory. If you wish to keep them, then *SMerge and OS_SpriteOp 11 will merge the sprite file sprites with those in memory. Any name clashes will result in the file sprite replacing the memory one.
There are two main ways of creating a sprite. You can grab a piece of screen memory using OS_SpriteOp 14 or 16, or *SGet. Alternatively, you can create a blank sprite with OS_SpriteOp 15 to be subsequently filled in. With this blank sprite, you can alter individual pixels or you can direct VDU operations into it. These are discussed later.
To create a mask, OS_SpriteOp 29 must be used. It will initialise all the pixels solid, so that all of the sprite is plotted. You must alter it afterwards to set the mask that you require.
The contents of a sprite may be manipulated in many ways.
You can copy, rename or delete a sprite in the following ways:
You can insert and delete rows and columns at any place you wish in the sprite. These are the operations that you need to do this:
A sprite can be flipped about its x or y axis. Flipping it about the x axis using OS_SpriteOp 33 or *SFlipX will make it appear upside down. Flipping it about the y axis with OS_SpriteOp 47 or *SFlipY will make it look back to front.
If a sprite is not a whole number of words wide, it is possible that part of each row on the left and right is 'wasted'; that is, it does not form part of the sprite image. To remove this wastage, OS_SpriteOp 54 will align the sprite with the left hand side. If more than 32 free bits are on the right of the sprite, then these words will be removed.
Sprites can be tacked together, either horizontally or vertically, using OS_SpriteOp 35. No extra memory is used to do this.
To check the size of a sprite, OS_SpriteOp 40 will return its width, height, screen mode and whether it has a mask or not.
If you wish to read a pixel in a sprite, then OS_SpriteOp 41 will return colour and tint for a given x and y coordinate in the sprite. To write a pixel colour, OS_SpriteOp 42 must be used. It is given the coordinates, colour and tint to use.
Similar to these last two SWIs, OS_SpriteOp 43 will read a mask pixel and OS_SpriteOp 44 will write it. Remember that a mask has the same number of bits per pixel as the image, but that the bits for each pixel must either be all set, or all clear.
The VDU drivers can be directed to put their output into a sprite instead of the screen. OS_SpriteOp 60 will switch output to a sprite or to the screen. OS_SpriteOp 61 will switch output to a mask or the screen.
The save area described earlier is used by these calls. The space required for a save area can be determined by calling OS_SpriteOp 62.
To plot a sprite on the screen, OS_SpriteOp 28 and 34 are the simplest to use. They plot the sprite at the current graphics cursor position, using the current GCOL action. OS_SpriteOp 48 and 49 are similar, but the coordinates and GCOL action are instead passed explicitly.
A sprite can be plotted at any magnification using OS_SpriteOp 50 and 52.
Like these SWIs, OS_SpriteOp 53 will plot a sprite using scale factors and a translation table, but it uses the anti-aliased colour technique that the font manager uses for characters.
OS_SpriteOp 51 will paint a character onto the screen using scale factors.
OS_SpriteOp 55 and 56 will plot a sprite or mask with a linear transformation, such as a shear, stretch or reflection.
There are ways of selecting a sprite so that it can subsequently be used by the VDU commands described below to plot sprites.
The VDU commands are included for compatibility only and in RISC OS are of very little use since they only allow access to the system sprite area, whereas you will more likely be using user sprite areas.
Any programs being written for the Wimp must not use these VDU commands because there is only one location storing the setting for the selected sprite, not one per process.
As well as '*SChoose and OS_SpriteOp 24, a sprite can be selected for VDU use by:
VDU 23,27,m,n|
where:
m = 0 | is equivalent to *SChoose n |
m = 1 | is equivalent to *SGet n |
Once a sprite has been selected by either of the three techniques above, it can be plotted using:
VDU 25,232 - 239,x;y;
The range of eight plot numbers are the standard plot options as defined in VDU 25 (see VDU 25). x and y are in OS coordinates.
R1 = &72 (reason code)
R2 = value passed in R0 to SpriteOp that caused output to switch
R3 = value passed in R1 to SpriteOp that caused output to switch
R4 = value passed in R2 to SpriteOp that caused output to switch
R5 = value passed in R3 to SpriteOp that caused output to switch
All registers preserved
Issued when output is switched from and to a sprite immediately after the output is switched.
This service call should not be claimed.
Controls the sprite system
R0 = reason code
Other registers depend on reason code
R0 preserved
Other registers depend on reason code
Interrupts are enabled
Fast interrupts are enabled
Processor is in SVC mode
SWI is not re-entrant
This call controls the sprite system. It is indirected through SpriteV.
The particular action of OS_SpriteOp is given by the reason code in R0 as follows:
R0 | Meaning | Page |
---|---|---|
2 | Screen save | |
3 | Screen load | |
8 | Read area control block | |
9 | Initialise sprite area | |
10 | Load sprite file | |
11 | Merge sprite file | |
12 | Save sprite file | |
13 | Return name | |
14 | Get sprite | |
15 | Create sprite | |
16 | Get sprite from user co-ordinates | |
24 | Select sprite | |
25 | Delete sprite | |
26 | Rename sprite | |
27 | Copy sprite | |
28 | Put sprite | |
29 | Create mask | |
30 | Remove mask | |
31 | Insert row | |
32 | Delete row | |
33 | Flip about x axis | |
34 | Put sprite at user coordinates | |
35 † | Append sprite | |
36 † | Set pointer shape | |
37 † | Create/remove palette | |
40 | Read sprite information | |
41 | Read pixel colour | |
42 | Write pixel colour | |
43 | Read pixel mask | |
44 | Write pixel mask | |
45 | Insert column | |
46 | Delete column | |
47 | Flip about y axis | |
48 | Plot sprite mask | |
49 | Plot mask at user coordinates | |
50 † | Plot mask scaled | |
51 † | Paint character scaled | |
52 † | Put sprite scaled | |
53 † | Put sprite grey scaled | |
54 | Remove lefthand wastage | |
55 † | Plot mask transformed | |
56 † | Put sprite transformed | |
57 † | Insert/delete rows | |
58 † | Insert/delete columns | |
60 | Switch output to sprite | |
61 | Switch output to mask | |
62 | Read save area size |
For details of each of these reason codes, see below.
Note that the reason codes marked with a dagger are provided by the SpriteExtend module, which must be loaded for them to work.
None
SpriteV
R0 = 2
R2 = pointer to pathname
R3 = palette flag (0 not to save, 1 to save)
R0, R2, R3 preserved
This saves the current graphics window as a sprite file. The file contains a single sprite called 'screendump'. If R3 is 0, no palette information is saved with the file; if it is 1, the current palette is saved. It is equivalent to *ScreenSave.
See reason code 3 to reverse the operation and load a screen.
SpriteV
R0 = 3
R2 = pointer to pathname
R0, R2 preserved
This plots a sprite directly from a file to the screen. It changes mode if necessary and sets the palette to the setting held in the file. The sprite is plotted at the bottom left of the graphics window. After a mode change, this is the bottom left-hand corner of the screen. It is equivalent to *ScreenLoad.
See reason code 2 to reverse the operation and save a screen.
SpriteV
R0 = 8
R1 = pointer to control block of sprite area
R0, R1 preserved
R2 = total size of sprite area in bytes
R3 = number of sprites in area
R4 = byte offset to the first sprite
R5 = byte offset to the first free word
This returns all the information contained in the control block of a sprite area.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 9
R1 = pointer to control block of sprite area
R0, R1 preserved
This initialises a sprite area. It is equivalent to *SNew when used with the system area.
If you are initialising a user sprite area, then you must first initialise two words in the area header:
Address | Contents of word |
---|---|
area + 0 | total size of area |
area + 8 | offset to first sprite (= 16, if the extension area is null) |
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 10
R1 = pointer to control block of sprite area
R2 = pointer to pathname
R0 - R2 preserved
This loads the sprite definitions contained in the file into the sprite area, overwriting any definitions stored there already. It is equivalent to *SLoad when used with the system area.
The sprite area must be initialised before you call this SWI.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 11
R1 = pointer to control block of sprite area
R2 = pointer to pathname
R0 - R2 preserved
This merges the sprite definitions contained in the file with those in the sprite area. It is equivalent to *SMerge when used with the system area.
Note that there must be enough free space in the sprite area to hold both the new file and the original sprites, since it is only after the new file has been loaded that any of the original sprites are replaced by new ones that have the same name.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 12
R1 = pointer to control block of sprite area
R2 = pointer to pathname
R0 - R2 preserved
This saves the contents of a sprite area to a file. It is equivalent to *SSave when used with the system area.
The first word of the sprite area (its size) is not saved.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 13
R1 = pointer to control block of sprite area
R2 = pointer to buffer
R3 = maximum name length (ie buffer size)
R4 = sprite number (position in workspace - the first one is numbered 1)
R0 - R2 preserved
R3 = name length
R4 preserved
This returns the name of the sprite whose position in the workspace (eg 3 for the third sprite) is given in R4. The name is placed in the buffer pointed to by R2 as a null-terminated string, the length of which is returned in R3.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 14 (&0E)
R1 = pointer to control block of sprite area
R2 = pointer to sprite name
R3 = palette flag (0 to exclude palette data, 1 to include it)
R0, R1 preserved
R2 = address of sprite (if in user sprite area)
R3 preserved
This defines the identified sprite to be the current contents of an area of the screen. It is delimited by the current and old cursor positions (inclusive). If the sprite already exists, it is overwritten. It is equivalent to *SGet when used with the system area.
Any part of the designated area which lies outside the current graphics window is filled with the current background colour in the sprite.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters. You must not call this SWI with bit 9 of R0 set; that is, R2 must always point to a sprite name.
SpriteV
R0 = 15 (&0F)
R1 = pointer to control block of sprite area
R2 = pointer to sprite name
R3 = palette flag (0 to exclude palette data, 1 to include it)
R4 = width in pixels
R5 = height in pixels
R6 = mode number
R0 - R6 preserved
This creates a blank sprite of a given size.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters. You must not call this SWI with bit 9 of R0 set; that is, R2 must always point to a sprite name.
None
SpriteV
R0 = 16 (&10)
R1 = pointer to control block of sprite area
R2 = pointer to sprite name
R3 = palette flag (0 to exclude palette data, 1 to include it)
R4 = left hand edge OS screen coordinate (inclusive)
R5 = bottom edge OS screen coordinate (inclusive)
R6 = right hand edge OS screen coordinate (inclusive)
R7 = top edge OS screen coordinate (inclusive)
R0, R1 preserved
R2 = address of sprite (if in user sprite area)
R3 - R7 preserved
This picks up an area of the screen, which is delimited by the coordinates supplied (inclusive), as a sprite. If the sprite already exists, it is overwritten.
Any part of the designated area which lies outside the current graphics window is filled with the current background colour in the sprite.
Setting bit 8 or 9 of R0 alters the interpretation of R1 - for a description see the chapter entitled Common parameters. You must not call this SWI with bit 9 of R0 set; that is, R2 must always point to a sprite name.
SpriteV
R0 = 24 (&18)
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0, R1 preserved
R2 = address of sprite (if in user sprite area), otherwise preserved
Select a particular sprite for subsequent plotting. That is, the VDU 25,232-239 commands will use the selected sprite. It is equivalent to *SChoose when used with the system area.
The returned address only remains valid until the next SpriteOp which may rearrange the sprite area, such as OS_SpriteOp 11 (merge sprite file) or OS_SpriteOp 25 (delete sprite).
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 25 (&19)
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
This deletes the definition of a particular sprite. It is equivalent to *SDelete when used with the system area.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 26 (&1A)
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = pointer to new name
R0 - R3 preserved
This changes the name of a sprite. An error is produced if a sprite of the new name already exists in the same sprite area. It is equivalent to *SRename when used with the system area.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 27 (&1B)
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = pointer to new name
R0 - R3 preserved
This copies a sprite within a sprite area. An error is produced if a sprite of the new name already exists in the same sprite area. It is equivalent to *SCopy when used with the system area.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 28
R1 = pointer to control block of sprite area
R2 = sprite pointer
R5 = plot action (see Plot action)
R0 - R2, R5 preserved
This plots the sprite identified with its bottom left corner at the current graphics cursor position using the plot action specified in R5.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 29
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
This creates a mask for the specified sprite with all pixels set to be solid.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 30
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
This removes the mask definition for a given sprite.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 31
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = row number
R0 - R3 preserved
This inserts a row in the sprite at the position identified, shifting all rows above it up one. All pixels in the new row are set to colour zero, or to transparent if the sprite has a mask. Rows are numbered from the bottom upwards with the bottom row being number zero. If the row number is equal to the height of the sprite it will go on top. Any value above this will generate an error.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 32
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = row number
R0 - R3 preserved
This deletes a row in the sprite at the position identified, shifting all rows above it down one. Rows are numbered from the bottom upwards with the bottom row being number zero. If the row number is greater than or equal to the height of the sprite it will generate an error.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 33
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
This takes the sprite identified and reflects it about the x axis so that it is upside down. Thus, its top row on entry becomes the bottom row on exit, and so on.
It is equivalent to *SFlipX when used on the system area sprites.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 34
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate at which to plot
R4 = y coordinate at which to plot
R5 = plot action (see Plot action)
R0 - R5 preserved
This plots a sprite at the external coordinates supplied, using the plot action supplied in R5.
No check is made that the plotted sprite's screen mode is compatible with the current screen mode; if they are not compatible you will get a display that may not be particularly useful.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 35
R1 = pointer to control block of sprite area
R2 = sprite pointer 1
R3 = sprite pointer 2
R4 = 0 to merge horizontally, or 1 to merge vertically
R0 - R4 preserved
This call can be used to merge two sprites of the same height or width into one sprite, tacking them together vertically or horizontally.
The sprites are appended horizontally in the following order:
The sprites are appended vertically in the following order:
The result of the merge is stored in sprite 1 and sprite 2 is deleted. Thus the merge does not consume any extra memory.
Attempting to merge two sprites with different vertical or horizontal sizes will result in an error.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 36
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = bitfield (see below)
R4 = x offset of active point
R5 = y offset of active point
R6 = scale factors (0 to scale for the mode)
R7 = pixel translation table
R0 - R3 preserved
This call sets 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 high resolution monochrome modes (eg mode 23), the pointer shape resolution is four times worse horizontally than the pixel resolution, and only colours 0, 1 and 3 can be used in the pointer shape definition. This call will cater for this 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.
R3 on entry is a bitfield composed of the following fields:
Bit | Meaning |
---|---|
0 - 3 | pointer shape number, currently in the range 1 - 4 |
4 | if clear, then set the pointer shape data |
5 | if clear, then set the palette from the sprite |
6 | if clear, then program the pointer shape number |
7 - 31 | reserved; must be zero |
Bits 4, 5, and 6 of this bitfield can be used to defer certain aspects of this call until later. For example, if you wanted to set up the pointer shape without displaying the pointer, bits 5 and 6 would be set.
The coordinates in R4 and R5 are relative pixels from the top left corner of the sprite.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 37
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = sub-reason code:
R0 - R2 preserved
R3 = size of palette or 0 if none (if R3 = -1 on entry); else preserved
R4 = pointer to palette or 0 if none (if R3 = -1 on entry)
R5 = mode (if R3 = -1 on entry)
This call creates a palette, removes a palette, or finds the size of the palette associated with a given sprite.
If you add or remove a sprite's palette when output is switched to the sprite you will invalidate the current display pointers In such cases you should switch output away from the sprite, modify the palette, and then switch output back to the sprite.
To create 256 entry palettes you must set bit 31 of R3 on entry. This facility is not available in RISC OS 2.
None
SpriteV
R0 = 40
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
R3 = width in pixels
R4 = height in pixels
R5 = mask status (0 for no mask, 1 for mask)
R6 = screen mode in which the sprite was defined
This returns information about the sprite, giving its width and height in pixels, whether the sprite has a mask and the screen mode in which the sprite was defined.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 41
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate (in pixels)
R4 = y coordinate (in pixels)
R0 - R4 preserved
R5 = colour
R6 = tint
Given x and y coordinates in R3 and R4 (in pixels relative to the bottom left of the sprite definition), this call returns the current colour of the pixel at that position.
The colour and tint returned depends on the mode. If it is not a 256 colour mode, then colour is from zero to the number of colours-1 and tint is zero. In 256 colour modes, the colour is from 0 to 63 and tint is either 0, 64, 128 or 192.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 42
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate (in pixels)
R4 = y coordinate (in pixels)
R5 = colour
R6 = tint
R0 - R6 preserved
Given x and y coordinates (in pixels relative to the bottom left of the sprite definition), and colour and tint in R5 and R6, this call sets the colour of the pixel at that position.
The colour and tint values used depend on the mode. If it is not a 256 colour mode, then colour is from zero to the number of colours-1 and tint is ignored. In 256 colour modes, the colour is from 0 to 63 and tint is either 0, 64, 128 or 192: ie only bits 6 and 7 are used.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 43
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate (in pixels)
R4 = y coordinate (in pixels)
R0 - R4 preserved
R5 = mask status (0 = transparent, 1 = solid)
Given x and y coordinates in R3 and R4 (in pixels relative to the bottom left of the sprite definition), this call returns the current state of the mask at that position.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 44
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate (in pixels)
R4 = y coordinate (in pixels)
R5 = mask status (0 = transparent, 1 = solid)
R0 - R5 preserved
Given x and y coordinates (in pixels from the bottom left of the sprite definition), and mask state in R5, this call sets the pixel at the position given to that mask.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 45
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = column number
R0 - R3 preserved
This inserts a column at the position identified, shifting all columns after it one place to the right. The new column is set to have either transparent or colour zero pixels, depending on whether the sprite has a mask or not. Columns are numbered from the left with the left-hand one being number zero.
If the column number is equal to the width of the sprite it will go after the right hand side. Any value above this will generate an error.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 46
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = column number
R0 - R3 preserved
This deletes a column from the position identified, shifting all columns after it one place to the left. Columns are numbered from the left with the left-hand one being number zero.
If the column number is greater than or equal to the width of the sprite it will generate an error.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 47
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
This takes the sprite identified and reflects it about the y axis so that it is facing in the opposite direction. Thus, its leftmost column on entry becomes the rightmost column on exit, and so on.
It is equivalent to *SFlipY when used with the system sprite area.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 48
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
This plots a sprite mask in the background colour and action with its bottom left corner at the graphics cursor position. That is, all 1 bits in the mask are plotted in the background colour and action, and all 0 bits are ignored. If the sprite has no mask, a solid rectangle the same size as the sprite is drawn in the current background colour and action (as if there was a mask which was completely solid).
The plot action for this call is the same as that for normal graphics operations, rather than that used in plotting sprites.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 49
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate at which to plot
R4 = y coordinate at which to plot
R0 - R4 preserved
This plots in the background colour and action through a sprite mask at the external coordinates supplied.
The plot action for this call is the same as that for normal graphics operations, rather than that used in plotting sprites.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 50
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate at which to plot
R4 = y coordinate at which to plot
R6 = scale factors
R0 - R6 preserved
A sprite mask is plotted on the screen, using the current background colour and action and the scaling factors provided.
The plot action for this call is the same as that for normal graphics operations, rather than that used in plotting sprites.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
None
SpriteV
R0 = 51
R1 = character code
R3 = x coordinate at which to plot
R4 = y coordinate at which to plot
R6 = scale factors
R0, R1, R3, R4, R6 preserved
The specified character is plotted on the screen with its lower left hand corner at the specified coordinate, using the current graphics foreground colour and action.
The plot action for this call is the same as that for normal graphics operations, rather than that used in plotting sprites.
None
SpriteV
R0 = 52
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate at which to plot
R4 = y coordinate at which to plot
R5 = plot action (see Plot action)
R6 = scale factors: 0 no scaling (ie 1:1, sprite pixel to screen pixel)
R7 = pixel translation table: 0 no translation
R0 - R7 preserved
This will plot a sprite on the screen using:
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 53
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = x coordinate at which to plot
R4 = y coordinate at which to plot
R5 = 0
R6 = scale factors
R7 = pixel translation table
R0 - R7 preserved
This call is similar to OS_SpriteOp 52, except that it performs anti-aliasing on the sprite as it scales it. This is the same technique that the Font Manager uses on characters. This means that the sprite must have been defined in a 4 bits per pixel mode (16 colours), and the pixels must reflect a linear grey scale, as with anti-aliased font definitions.
This call is considerably slower than OS_SpriteOp 52 (Put sprite scaled) and should only be used when the quality of the image is of the utmost importance. To speed up redrawing of an anti-aliased sprite, it is possible to draw the image into another sprite (using OS_SpriteOp 60 - switch output to sprite), which can then be redrawn more quickly.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 54
R1 = pointer to control block of sprite area
R2 = sprite pointer
R0 - R2 preserved
In general, sprites have a number of unused bits in the words corresponding to the left and right hand edges of each pixel row. This call removes the left hand wastage, so that the left hand side of the sprite is word aligned.
The right hand wastage is increased by the number of bits that were removed. If this is now more than 32 bits then a whole word is removed from each row of the sprite, and the rest of the sprite area moved down to fill the gap.
Note that when you switch output to a sprite using OS_SpriteOp 60 or 61, the left-hand wastage is also removed.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 55 (PlotMaskTransformed) or 56 (PutSpriteTransformed)
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = flag word:
--
This call is not available in RISC OS 2.
The source coordinates are inclusive at the bottom-left, and exclusive at the top-right. If no source rectangle is given, the default is x0 = 0, x1 = width of sprite (in pixels), and y0 = height of sprite (in pixels), y1 = 0. Note that the y coordinates are the reverse of what you might expect; this is only relevant when plotting to a destination parallelogram (see below).
When specifying a destination parallelogram, the source rectangle is mapped onto the destination as follows:
x0,y0 | X0,Y0 |
x1,y0 | X1,Y1 |
x1,y1 | X2,Y2 |
x0,y1 | X3,Y3 |
In future it may be possible to set the destination to an arbitrary quadrilateral, rather than a parallelogram. In order to reserve this possibility, the current version returns an error if the destination is not a parallelogram.
For PutSpriteTransformed, the sprite is plotted through its mask only if it both has one, and bit 3 of R5 is set. R5 is ignored for PlotMaskTransformed.
The SWI returns an error if any of R3 bits 2 - 31 are set, to ensure that these are left clear by software developers.
The SWI covers exactly those pixels on the screen that a call to Draw_Fill would produce for a rectangle of the same size with the same transformation matrix, where it is filling to half-way through the boundary.
When plotting using a destination parallelogram, the source rectangle must be entirely within the sprite. For plotting with a matrix, the source rectangle will be clipped to the sprite boundaries prior to transformation; any of the sprite's pixels outside the source rectangle will behave as if they had a transparent mask.
If the source rectangle (after clipping, if using a matrix) has no area, i.e. x0 = x1 OR y0 = y1 then an error will be generated, as it is not possible to choose a colour in which to fill the destination.
Note that the SWI does allow x0>x1 or y0>y1 or both. When plotting with a matrix there is no difference between x0 and x1 swapped, or y0 and y1 swapped, but when specifying a destination parallelogram the image will be reflected.
Due to the mechanism of the routine the accuracy is not absolute. The SWI will always cover the same area as a Draw filled path, but not necessarily with the right source pixel data from the sprite. The worst possible error (in a fraction of a source pixel) at one end of the plotted area is given by destination width or height/65536.
The table below gives more information on the maximum errors attainable:
Destination size | Worst possible error in source pixels |
---|---|
5 | 0.0000763 |
10 | 0.0001526 |
50 | 0.0007629 |
100 | 0.0015259 |
500 | 0.0076294 |
1000 | 0.0152588 |
5000 | 0.0762939 |
10000 | 0.1525879 |
(The largest output possible is 32767 pixels)
For example, when plotting a sprite to a destination width of 5000 pixels, the worst error possible in the position in the source rectangle of the final pixel plotted is about 1/13 of a source pixel.
Note that if these errors (usually too small to notice) must be avoided then the sprite should be plotted in parts - perhaps by dividing the plotting into four areas.
None
R0 = 57 (InsertDeleteRows) or 58 (InsertDeleteColumns)
R1 = pointer to control block of sprite area
R2 = sprite pointer
R3 = row/column to start deletion at or to insert before
R4 = number of rows/columns to insert (if +ve) or delete (if -ve)
R0 - R4 preserved
This call is not available in RISC OS 2.
For insertion R4 > 0, and R3 specifies the row or column to insert before. For a sprite of n rows × m columns the rows are numbered from 0 at the bottom to n-1 at the top, and columns from 0 at the left to m-1 at the top. Thus to insert rows/columns on the edges of the sprite:
R0 | R3 | Insertion point |
---|---|---|
57 | 0 | bottom edge (ie before the first row) |
n | top edge (ie before the row beyond the last row) | |
58 | 0 | left edge (ie before the first column) |
m | right edge (ie before the column beyond the last column) |
The inserted rows/columns are set to colour 0. If the sprite has a mask then rows/columns are inserted into that as well, and the inserted area is transparent.
For deletion R4 < 0, and R3 specifies the first row or column to be deleted. The rows/columns from R3 to (R3-R4-1) will be deleted. An error will be given if R3 or R4 are out of range for the sprite.
None
SpriteV
R0 = 60
R1 = pointer to control block of sprite area
R2 = sprite pointer to switch to sprite, or 0 to switch to screen
R3 = pointer to save area, or 0 for no save area, or 1 for system save area
R0 preserved
R1 = previous value
R2 = previous value
R3 = previous value
This call can cause VDU calls to be sent to the screen memory, or to a sprite's image.
R2 has its usual function as a sprite pointer; alternatively it can be zero, in which case output is switched to the screen.
The purpose of the save area is to preserve your own context should anyone switch output away from you. This call can be thought of as switching to a particular graphics context as well as switching output.
The save area's location (specified in R3) can have a number of values. If it is zero, then no save area will be used; you should avoid this if possible. If it is one, then the system save area is used; RISC OS uses this area to save the screen's graphics context, and you should not use this area yourself if you wish to preserve the screen's graphics context. Any other value of R3 is considered to be a pointer to a user specified save area, usually used to preserve a sprite's graphics context.
When you make this call, the current graphics state is saved to the current graphics save area, the first word of which is set to a non-zero value. The save area specified by R3 is then made the current save area. If its first word is non-zero, it is assumed to contain a graphics context, which is restored; if its first word is zero (or no save area is specified), then it is assumed to be a new save area, and the VDU state is instead initialised to suitable defaults for the mode in which the sprite was defined. Output is then switched, as specified by R2.
You can find the required size of a save area by calling OS_SpriteOp 62.
You must not poll the Wimp whilst output is switched to a sprite, as other applications will not expect this.
For more details of save areas, and examples of their use, see the chapter entitled Save area.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 61
R1 = pointer to control block of sprite area
R2 = sprite pointer to switch to mask, or 0 to switch to screen
R3 = pointer to save area, or 0 for no save area, or 1 for system save area
R0 preserved
R1 = previous value
R2 = previous value
R3 = previous value
This call can cause VDU calls to be sent to the screen memory, or to a sprite's mask.
See OS_SpriteOp 60 for a general description of how this call works.
A sprite's mask has the same number of bits per pixel as its image, where a value of 0 is a transparent pixel and a value of all 1's represents a solid pixel. For example, &0F for 4 bits per pixel. Other values are not permitted. Hence when plotting into a sprite's mask, the only colours that should be used are 0 and (number of colours -1), that is:
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
R0 = 62
R1 = pointer to control block of sprite area
R2 = sprite pointer, or 0 for the screen
R0 - R2 preserved
R3 = size of required save area in bytes
This calls calculates how large a save area must be for a given sprite. This is a constant for a particular release of RISC OS, but may vary between versions. Remember that a save area must be word aligned.
Setting bit 8 or 9 of R0 alters the interpretation of R1 and R2 - for a description see the chapter entitled Common parameters.
SpriteV
Sets the configured amount of memory reserved for the system sprite area
*Configure SpriteSize mK|n
mK - number of kilobytes of memory reserved
n - number of pages of memory reserved; n 127
*Configure SpriteSize sets the configured amount of memory reserved for the system sprite area. If you pass a parameter of 0, then no space is reserved for system sprites. The default value is one page of memory.
You can also use OS_ChangeDynamicArea to alter dynamically the system sprite size. For more information, refer to the chapter entitled Memory Management.
The change takes effect on the next hard reset.
*Configure SpriteSize 20K
None
None
None
Selects a sprite for use in subsequent sprite plotting operations
*SChoose sprite_name
sprite_name - name of a sprite in the system sprite area
*SChoose selects a sprite from the system sprite area for use in subsequent sprite plotting operations. It is used in conjunction with VDU 25,232-239 operations. You should see the warning in the VDU commands about using these obsolescent VDU calls.
The sprite name is not case-sensitive.
*SChoose fish
None
SpriteV
*SCopy source_sprite_name dest_sprite_name
source_sprite_name - name of source sprite in the system sprite area
dest_sprite_name - name of destination sprite (to be placed in the system sprite area)
*SCopy makes a copy of the source sprite within the system sprite area, and renames it as the destination sprite. An error is generated if the destination sprite already exists.
*SCopy acorn squirrel
None
SpriteV
Loads the contents of a sprite file into the graphics window
*ScreenLoad filename
filename - a valid pathname, specifying a sprite file
*ScreenLoad loads the contents of a sprite file (saved, for example, with the *ScreenSave command) into the graphics window, which is typically the whole screen.
It changes mode if necessary and sets the palette to the setting in the file. The first sprite in the file is plotted at the bottom left hand corner of the graphics window. After a mode change, this is the bottom left hand corner of the screen.
Note: You may get unpredictable results when using *ScreenLoad to load a sprite that was not created by *ScreenSave. The same applies to the equivalent SWIs.
*ScreenLoad $.sprites.animals.koala
*ScreenSave
SpriteV
Saves the contents of the graphics window and its palette to a file
*ScreenSave filename
filename - a valid pathname, specifying a file
*ScreenSave saves the contents of the graphics window (typically the whole screen) and its palette to a file, which is saved as a sprite. The sprite file created will contain one sprite called 'screendump'.
You can then load this file into Paint or Draw.
*ScreenSave My.Pic
*ScreenLoad
SpriteV
*SDelete sprite_name1 [sprite_name2...]
sprite_name1 - name of a sprite in the system sprite area
sprite_name2... - optional extra sprites to delete
*SDelete deletes one or more sprites from the system sprite area.
If an error occurs (such as a sprite not existing) *SDelete will stop immediately, and no further sprites will be deleted.
*SDelete fish cake elephant
None
SpriteV
Reflects a sprite in the system sprite area about its x axis
*SFlipX sprite_name
sprite_name - name of a sprite in the system sprite area
*SFlipX reflects a sprite in the system sprite area about its x axis so it is upside down.
*SFlipX sloth
*SFlipY
SpriteV
*SFlipY sprite_name
sprite_name - name of a sprite in the system sprite area
*SFlipY reflects a sprite in the system sprite area about its y axis so it faces in the opposite direction.
*SFlipY sloth
*SFlipX
SpriteV
sprite_name - name of new sprite in the system sprite area
*SGet gets a sprite from a rectangular area of the screen, defined by the two most recent graphics positions (inclusive). It then saves this sprite in the system sprite area with the given name. If the sprite already exists, it is overwritten.
Any part of the designated area which lies outside the current graphics window is filled in the sprite with the current background colour.
*SGet screenpart
*ScreenSave
SpriteV
*SInfo
None
*SInfo displays information on the system sprite workspace. It prints out the amount of system sprite workspace currently reserved, the amount of free space in that workspace and the number of sprites defined.
*SInfo Sprite status 8 Kbytes sprite workspace 7328 byte(s) free 2 sprite(s) defined
None
SpriteV
Lists the names of all the sprites in the system sprite area
*SList
None
*SList lists the names of all the sprites in the system sprite area.
*SList !koala !sloth
None
SpriteV
*SLoad filename
filename - full name of file to load
*SLoad loads a file containing sprite definitions into the system sprite area. If there is insufficient memory, then an error is given and nothing is loaded. Any sprites which are in memory when this command is given are lost.
*SLoad $.sprites.animals.koala
*ScreenLoad
SpriteV
Merges the sprites in a file with those in the system sprite area
*SMerge filename
filename - full name of file to load
*SMerge merges the sprites in a file with those in the system sprite area. If there is insufficient memory, then an error is given and nothing is loaded. Any sprites in memory with the same name as any in the file are lost.
Note that there must be enough free space in the sprite area to hold both the new file and the original sprites, since it is only after the new file has been loaded that any of the original sprites are replaced by new ones that have the same name.
*SMerge $.sprites.animals.koala
None
SpriteV
*SNew
None
*SNew deletes all the sprites in the system sprite area, and so frees all the sprite workspace.
None
SpriteV
*SRename old_sprite_name new_sprite_name
old_sprite_name - name of a sprite in the system sprite area
new_sprite_name - new name of the sprite
*SRename renames a sprite within the system sprite area. An error is generated if a sprite having the new name already exists.
A sprite name can contain any sequence of printable characters, other than a space; although upper-case letters will be changed to lower-case ones.
*SRename thong flipflop
None
SpriteV
*SSave filename
filename - name of file to save
*SSave saves all the sprites currently in the system sprite area as a sprite file. You can then load or merge the file later on.
*SSave $.sprites.animals.koala
*SLoad, *SMerge
SpriteV
By careful use of sprite operations and ColourTrans, sprites with 256 entry palettes can be created and displayed on all RISC OS machines. Of course, this ability to create and process a sprite with (say) 256 grey levels in it does not magically endow the hardware with the ability to display 256 grey levels! The display will be as close as possible (ie 16 grey levels with standard hardware), but will not be exact unless the machine's hardware has been extended using a product such as a graphics enhancer expansion card.
A 256 entry palette sprite is precisely like a 16 entry palette sprite, save that there are 256 palette entries, each one consisting of a pair of 'palette entry' words of the form &BBGGRR00 as for ColourTrans. All bits of the entry are significant.
If you use OS_SpriteOp 15 to create a sprite with a palette for a 256 colour mode, the palette will not have 256 entries. To create a sprite with the full 256 palette entries, the best thing to do is to create one with no palette, and then to add 2048 to the following entries:
Entry | Meaning |
---|---|
word 4 of Sprite Area control block | offset to first free word |
word 1 of Sprite control block | offset to next sprite |
word 9 of Sprite control block | offset to sprite image |
word 10 of Sprite control block | offset to transparency mask |
You should then write the 256 double words of palette entries starting at word 12 of the sprite, keeping both items in a pair identical:
SYS "OS_SpriteOp",&10F,sarea,name$,0,x,y,spritemode sptr=sarea+sarea!8 pal=sptr+11*4 !(sptr+8*4)+=2048 !(sptr+9*4)+=2048 !sptr+=2048 !(sarea+12)+=2048 FOR i=0 TO 255 entry=palette!(i<<2) AND NOT &FF pal!(i*8)=entry pal!(i*8+4)=entry NEXT
All sprite operations work on the 256 entry palette sprite. One can even switch output to it and generate 256 grey level output into it (with appropriate care over the GCOL and TINT values required by RISC OS). Sprite areas containing 256 entry palette sprites may be loaded, saved etc.
After creation, the 256 entry palette sprite behaves just like all the others, so it is important you can distinguish it on the occasions when you need to (such as when displaying it on the screen).
A 256 entry palette sprite will have the lowest of words 9 and 10 of the sprite control block equal to 2048+44 (&82C). If you already know that the sprite has no transparency mask, then you can test only word 9.
The SWI ColourTrans_SelectTable takes a 64 entry palette sprite (and 2, 4 and 16) and returns a pixel translation table as needed for OS_SpriteOp 52. For a 256 entry sprite, one needs to build a similar pixel translation table directly. The following code will compute a pixel translation table for any sprite which hasn't a transparency mask:
IF sptr!32=44 THEN palptr=0 ELSE FOR grab=0 TO 2048-8 STEP 8 paltemp!(grab>>1)=sptr!(grab+44) NEXT palptr=paltemp ENDIF FOR i=0 TO 255 pixtrans?i=i NEXT IF sptr!32=2048+44 THEN FOR i=0 TO 255 SYS "ColourTrans_ReturnColourNumber",palptr!(i<<2) TO pixtrans?i NEXT ELSE SYS "ColourTrans_SelectTable",m,palptr,-1,-1,pixtrans ENDIF spx=-1 FOR i=0 TO 255 IF pixtrans?i<>i THEN spx=pixtrans NEXT
spx is equal either to -1 if no translation needs to be done (which speeds up OS_SpriteOp 52 a lot), or to pixtrans; it is passed to OS_SpriteOp 52 in register 7.
The ability to store, process and display 256 entry palette sprites represents a small but useful gain for the RISC OS desktop. Common formats can be converted to sprites without any loss of information and meaningfully displayed. It's still a good idea to use the default desktop palette whenever possible.