MetaSprite

© Cerilica 2022-2024

MetaSprite allows MetaData to be embedded within individual Sprites or (from v0.20) within the whole sprite file, extends the types of Palette that can be created, and fixes several problems with ColourTrans’ handling of 256 colour Sprites.

NEW! I’ve extended MetaSprite’s API to manipulate File MetaData in the sprite file’s Extension Area as well as the existing Sprite MetaData functionality.

Note that despite !Paint being the de facto RISC OS Sprite editor, it dates to RISC OS 2.0 and hence predates some of the APIs that MetaSprite modifies – !Paint is therefore very bad at coping with modified Sprites, and ought to be updated to use the APIs provided by RISC OS 3.0. I don’t think that would be rushing things, under the circumstances. Pleasingly, !Draw seems to manage perfectly.

Most interchange bitimage formats support MetaData in some form, so it’s about time that RISC OS Sprites did too. However, this is not limited to mere Title, Author and Creation Date strings. Instead, MetaSprite turns the Sprite into a chunky image format more akin to TIFF or JPEG, and as such the Sprite can be augmented with arbitrary amounts of binary information, such as an ICC Profile or Exif Camera Settings.

As this is a complicated subject and this is a programmer’s API, I’m not going to provide any technical details on this page. Download the zip file above. It contains an API document, a lengthy technical explanation, example Sprite and DrawFile exhibits, and a couple of demo programs in legible Basic.

I am currently using MetaData in sprites to implement:

There’s so many other possible applications – a very exciting and powerful module.

Bonus:

Also includes the NoSpriteImage module at no additional charge!

NoSpriteImage formalises and enables a Sprite construction containing no Image pixels, for those Sprites intended to be plotted as a Mask only.

Again, there is a technical document, and a couple of example files.

This is an experiment. I’m not sure how I feel about the results.

History

0.10 (21 Feb 2022)  Initial candidate

0.11 (04 Apr 2022)  Removal of last MetaData chunk removes Data Area

0.12 (22 Apr 2022)  Small bugfix to SpriteOp,36 so “HOT” works correctly

0.20 (12 Mar 2023) NEW SpriteOp,23 for File MetaData

0.21 (26 Mar 2023) Bugfix for obscure combination of SpriteOps 37 and 23.

0.22 (29 Mar 2023) Unpaletted 8bpp with MetaData

0.23 (31 Mar 2023) Fix for metadata remove: ULTIMATE item is not ONLY item

0.24 (30 Sep 2024) ErrorLookup ! Slight fix to ExtensionArea ChangeMem

0.30 (01 Oct 2024) Significant bugfix for zero-length data

0.31 (09 Dec 2024) Bugfix for malformed extension areas (eg OvPro)

LongSpriteNames

Current version is 0.04 (11 Dec 2024) [32bit]

Uses MetaSprite to enable Sprites to have long names. There’s no limit on the length, but as they’re not subject to a 12-byte maximum, they must be space or ctrl terminated.

Currently adds three SpriteOps to deal with longnames:

SpriteOp,&x8D  Return long name or find sprite index

 => R0 = &x8D (+&100 if R1=Area; +&200 if R2=ptr - only useful for R4=-1)

    R1 = Area (if R0>&100)

    R2 = if R4=-1 and R0=&28D:  Sprite Ptr

         if R4=-1 and R3<>0:    Sprite name,termi (ctrl or space)

         if R4=-1 and R3=0:     Sprite name,termi (max 12 bytes) 

         if R4>0:               Buffer for sprite name,0 (or 0 to read length)

    R3 = if R4=-1:  0 to treat R2 as an old 12-byte name, else longname,termi

         if R4>0:   length of buffer in R2 in which to return the name

    R4 = >0 to return name of nth sprite

         -1 to return index of sprite with given name (or SpritePtr)


 <= R3 = if R4 was >0: length of name (even if it didn't fit)

    R4 = if R4 was -1: index

SpriteOp,&x98  Find sprite address by long name

 => R0 = &x98 (+&100 if R1=Area; +&200 obviously makes no sense)

    R1 = Area (if R0>&100)

    R2 = Name,termi (space or control)


 <= R2 = SpritePtr

SpriteOp,&x9A  Rename long sprite name

 => R0 = &x9A (+&100 if R1=Area; +&200 if R2=ptr)

    R1 = Area (if R0>&100)

    R2 = old name,termi (if R0<&200) or SpritePtr (if R0=&29A)

    R3 = new name,termi (spc or ctrl)

I had considered using R0b7 to enable longnames for all SpriteOps, but that seemed a bit greedy. Also, shortnames are 12-bytes long for performance reasons, so it’s better to use longnames to find a Sprite (SOP,&98) and then pass that address to ColourTrans and SpriteOp.

SharedPals

Current version is 0.01 (24 Apr 2024) [32bit]

Uses MetaSprite (required) to enable Sprites to share the Palette of  another named Sprite (or of a Palette resource in the Sprite Extension Area).

Written because somebody described some horrific hardwired hack employed by a RISC OS distribution I won't mention, and I realised I wanted a general solution. A MetaData chunk in the Sprite contains the name of the Sprite whose Palette should be used (or the name of a Palette in the Extension Area).

OS_SpriteOp,37 (Create/find/remove palette) will correctly locate the Palette even if it's in another Sprite (or the Extension Area). However, you MUST pass R1=Area EVEN WHEN R2=SpritePtr (you should ALWAYS provide the SpriteArea to both SpriteOp and ColourTrans to allow for future expansion).

OS_SpriteOp,39 (Create/find/remove metadata) should be used to attach a PalN palette name to the sprite instead of having its own palette. This contains a null-terminated name which is either the name of a Sprite in the same Area, or of a Palette in an NPal chunk in the Extension Area. Note that sprite names are MUCH safer as they survive sprite merging - nothing merges Extension Areas at all, sadly.