/--------------------------------------\
|                SFToSpr               |
| Star Fighter 3000 graphics converter |
|        Christopher Bazley, 2000     |
|       Version 3.94 (02 Aug 2022)     |
\--------------------------------------/
N.B. This text is best viewed at a display width of 77 columns.

-----------------------------------------------------------------------------
1   Introduction and Purpose
    ========================

  SFToSpr is a graphics file format converter. It converts between the file
formats used internally in the game 'Star Fighter 3000' and the RISC OS
sprite file format.

  Converting the game's graphics to sprite format allows them to be viewed
or edited in other RISC OS applications, including the 'Paint' sprite editor
bundled with the computer. New graphics may be authored and then converted
to game format using SFToSpr.

  An alternative application, SFSkyEdit, is a dedicated editor for SF3000
sky colours files. As such, it offers a more user-friendly interface than
the combination of SFToSpr and a sprite editor. However, a sprite editor is
more flexible in that it allows you to manipulate the raw pixel data.

-----------------------------------------------------------------------------
2   Requirements
    ============

   RISC OS 3.10 or better.
   A !System directory (which must have been 'seen' by the Filer).
   The Toolbox modules (in !System or in ROM with RISC OS 3.6 and later).

  If any of the above facilities are unavailable then the program will fail
to load, with an error message describing the problem.

-----------------------------------------------------------------------------
3   Quick Guide
    ===========

  I have implemented an interface which is similar to the RISC OS 'Squash'
application, so hopefully everyone will be familiar with this. Interactive
help is also fully implemented.

  To get going, load SFToSpr and an icon will be installed on the icon bar.
Open your !Star3000 game directory, and find the directory named
"LandScapes" (this may be in a sub directory "Disc2"). Drag this directory to
the SFToSpr icon and a save dialogue box should pop up.

  Ensure that the 'SF3000 to sprite' radio button is set, then drag the
directory icon from the save box to a directory display to set the output
location. A progress window will appear for a few seconds before the
conversion of SF3000 graphics to Sprite files is complete.

  On opening the output directory you will find sub-directories named
"Planets", "Sky" and "Sprites". Respectively these should contain pictures of
celestial bodies, the dithered colours used to paint different skies, and the
tile graphics used to give an illusion of detail to the ground texture map.
You can now open these sprite files in your favourite editor and start
messing around with them.

-----------------------------------------------------------------------------
4   User Manual
    ===========

4.1 Data input and output
    ---------------------
  SFToSpr will claim files of type 'SFSkyPic' (&406) and 'SFMapGfx' (&407)
that are double-clicked in a directory display. It converts the graphics
directly to sprite format and directs the output to a file in your !Scrap
directory. This temporary file is then run, which should result in it being
opened by a sprite editor (probably Paint).

  SFToSpr loads files of type 'SFSkyCol' (&404), 'SFSkyPic' (&406) and
'SFMapGfx' (&407) that are dropped on its icon bar icon. Bitmap images (in
sprite format) or metadata (in CSV format) can be extracted. A dialogue box
will open to allow you to set the output type and destination.

  CSV (an abbreviation of 'comma-separated values') is a delimited data
format where fields are separated by the comma character and records are
separated by carriage return and/or linefeed.

  SFToSpr also loads files of type 'Sprite' (&FF9) that are dropped on its
icon bar icon. It will automatically decide whether to convert the sprites
to sky colours, sky pictures or map graphics. A dialogue box will open to
allow you to set the output destination and edit the metadata to be included
in the output file. Files of type 'CSV' (&DFE) can be dropped on this
dialogue box to replace the displayed metadata.

  SFToSpr also accepts directories and applications dropped on its icon bar
icon. A dialogue box will open to allow you to set up a batch operation,
including the output destination.

  The 'Multiple saveboxes' option on the iconbar menu controls whether to
allow multiple saveboxes, or only one at a time. You must enable this
option to meaningfully support dragging of multi-object selections from a
directory display. When not ticked (default state), opening a new savebox
will automatically close any existing savebox.

4.2 Extracting data from a SF3000 sky colours file
    ----------------------------------------------
  To extract data from a SF3000 sky colours file, drag it to the SFToSpr
icon on the icon bar. When it has been decompressed, a save dialogue box
with three radio buttons will appear.

  If the 'Images & data' option is set then the render offset and stars
height from the input file will be embedded in the output sprite file as
'extension data' (between the area header and sprite data). These values are
used by SF3000 when drawing a sky; embedding them in the sprite file allows
them to be easily restored when converting back to SFSkyCol format.

  The output file will contain a single sprite with dimensions of 4 by 126
pixels, a resolution of 45 dots per inch, 8 bits per pixel, and no palette
or mask.

  If the 'Images only' option is set then the sprite file will contain only
pixel data extracted from the SFSkyCol file. This option is provided for
compatibility with any sprite editors that do not cope with extension data
(the size of which is negligible).

  If the 'Data set only' option is set then the sole output will be a CSV
file containing the render offset and stars height (as the first and second
field of the first record, respectively).

  To overwrite the input SFSkyCol file (probably unwise) just click the
'Save' button or press the Return key. Alternatively you can drag the file
icon from the save box to a directory display of your choice.

4.3 Extracting data from a SF3000 sky pictures file
    -----------------------------------------------
  To extract data from a SF3000 sky pictures file, drag it to the SFToSpr
icon on the icon bar. When it has been decompressed, a save dialogue box
with three radio buttons will appear.

  If the 'Images & data' option is set then the paint offsets from the input
file will be embedded in the output sprite file as 'extension data' (between
the area header and sprite data). These pixel coordinate offsets are used by
SF3000 when drawing sky pictures; embedding them in the sprite file allows
them to be easily restored when converting back to SFSkyPic format.

  Each sprite in the output file will have dimensions of 34 by 36 pixels, a
resolution of 45 dots per inch, 8 bits per pixel, and no palette or mask.

  If the 'Images only' option is set then the sprite file will contain only
pictures extracted from the SFSkyPic file. This option is provided for
compatibility with any sprite editors that do not cope with extension data
(the size of which is negligible).

  If the 'Data set only' option is set then the sole output will be a CSV
file containing coordinate offsets. The first record will be the offsets for
image 0, and the second will be the offsets for image 1. Within each record,
the first field will be the vertical offset and the second field the
horizontal offset.

  To overwrite the input SFSkyPic file (probably unwise) just click the
'Save' button or press the Return key. Alternatively you can drag the file
icon from the save box to a directory display of your choice.

4.4 Extracting data from a SF3000 map graphics file
    -----------------------------------------------
  To extract data from a SF3000 map graphics file, drag it to the SFToSpr
icon on the icon bar. When it has been decompressed, a save dialogue box
with three radio buttons will appear.

  If the 'Images & data' option is set then the animations data from the
input file will be embedded in the output sprite file as 'extension data'.
This data tells SF3000 how to animate ground explosions; embedding it in the
sprite file allows it to be easily restored when converting back to SFMapGfx
format.

   Each sprite in the output file will have dimensions of 16 by 16 pixels, a
resolution of 45 dots per inch, 8 bits per pixel, and no palette or mask.

  If the 'Images only' option is set then the sprite file will contain only
the tile graphics extracted from the SFMapGfx file. This option is provided
for compatibility with any sprite editors that do not cope with extension
data (the size of which is negligible).

  If the 'Data set only' option is set then the sole output will be a CSV
file containing the animations data. The first record will be the tile
numbers for the first animation, the second will be the tile numbers for the
second animation, and the third will be the triggers for the second
animation (for details please refer to section 4.8).

  To overwrite the input SFMapGfx file (probably unwise) just click the
'Save' button or press the Return key. Alternatively you can drag the file
icon from the save box to a directory display of your choice.

4.5 Converting a sprite to SF3000 sky colours
    -----------------------------------------
  To convert a sprite to SF3000 sky colours, drag the sprite file to the
SFToSpr icon. The input file must contain a sprite named "sky", with
dimensions of 4 by 126 pixels, no internal wastage (left or right), and a
colour depth of 8 bits per pixel. The resolution and any mask or palette is
ignored.

  When the conversion is complete, an unusual save box will appear. It
includes two values that affect how SF3000 draws the sky. Higher render
offset values cause more of the lower colour bands to be compressed near the
horizon, when the viewer is at ground level. The stars height specifies the
height at which SF3000 begins to plot stars.

  These values may be altered using the bump up/down arrows or by typing
into the writable fields. You can also update them by dragging a CSV file to
the dialogue box, if it contains values in the same format output by SFToSpr.

  To overwrite the input sprite file (probably unwise) just click the 'Save'
button or press the Return key. Alternatively you can drag the SFSkyCol file
icon from the save box to a directory display of your choice.

4.6 Converting sprites to SF3000 sky pictures
    -----------------------------------------
  To convert sprites to SF3000 sky pictures, drag a sprite file to the
SFToSpr icon. The input file must contain one or more sprites with
dimensions of 34 by 36 pixels, no internal wastage (left or right), and a
colour depth of 8 bits per pixel. The resolution and any mask or palette is
ignored. The sprites must be named in the form "planet_n", where 'n' is
either 0 or 1. They need not be in numerical order, and if there is a
"planet_1" sprite but no "planet_0" then the second picture will be plain
black in the output file.

  When the conversion is complete, an unusual save box will appear. The
highest numbered sprite found in the input file will be displayed in the top
right-hand corner. Most of the dialogue box is devoted to the paint offsets
to be used when rendering the two pictures. These values may be altered
using the bump up/down arrows or by typing into the writable fields. You can
also update them by dragging a CSV file to the dialogue box, if it contains
values in the same format output by SFToSpr.

  To overwrite the input sprite file (probably unwise) just click the 'Save'
button or press the Return key. Alternatively you can drag the SFSkyPic file
icon from the save box to a directory display of your choice.

4.7 Converting sprites to SF3000 map graphics
    -----------------------------------------
  To convert sprites to SF3000 map graphics, drag a sprite file to the
SFToSpr icon. The input file must contain one or more sprites with dimensions
of 16 by 16 pixels, no internal wastage (left or right) and a colour depth
of 8 bits per pixel. The resolution and any mask or palette is ignored. The
sprites must be named in the form "tile_n", where 'n' is a map tile number
between 0 and 254. They need not be in numerical order, and any unfilled
gaps in the sequence will result in black tile graphics in the output file.

  When the conversion is complete, an unusual save box will appear. The
highest numbered sprite found in the input file will be displayed in the top
right-hand corner. Most of the dialogue box is devoted to the two splash
animations and triggers for the second animation (see section 4.8). The tile
numbers may be altered using the bump up/down arrows or by typing into the
writable fields. You can also update them by dragging a CSV file to the
dialogue box, if it contains values in the same format output by SFToSpr.

  To overwrite the input sprite file (probably unwise) just click the 'Save'
button or press the Return key. Alternatively you can drag the SFMapGfx file
icon from the save box to a directory display of your choice.

4.8 Map tile animations
    -------------------
  Two splash animations define what happens to the ground map when it is
damaged by a laser shot or explosion. Each animation consists four map tile
numbers that form a progression from excited to dead ground. In the "Earth"
map tiles set, the first animation is fiery for a hit on land, and the
second animation is splashy water for a hit on sea.

  By default, the first splash animation will be used all the time. To make
use of the alternative splash graphics you must set the '2nd splash
triggers', which define when the 2nd animation should be used. These four
numbers are used to check against the number of the map tile tile at the
position where the damage is to be inflicted.

  Each number in the second splash triggers stands for two map tiles - both
the tile number cited the one following it numerically, i.e. tile 'n' and
'n + 1'. SFToSpr attempts to illustrate this by showing the implicit second
tile number in a display field which is updated in parallel with the first
(editable) tile number.

  This is a kludge to allow dual-surface landscapes such as sea/land
("Earth", "Warrior"), or rock/lava ("Chem"). It is just about possible, by
doubling up the map tile numbers as described above, to specify a worthwhile
number of tiles of an alternate surface. You will need to be careful how the
map tile graphics are numbered in order to make good use of this feature.

  Conventionally, four of the second splash triggers (two pairs) are
assigned to the map tiles of the second splash itself. If you don't do this
then weird effects will occur - water turning to earth, etc. SFToSpr will
warn you if you don't include the tile numbers of the second splash in its
triggers (though the "Death" map graphics illustrate a legitimate exception).

  The example below from the "Earth" set shows how just two values (i.e. four
tile numbers) in the second splash triggers can be used to cover the
animation itself. Having assigned two trigger numbers to the first and third
splash tiles, there is room for four other sea tiles (in this case 0,1
and 137,138):

2nd splash triggers:   169---->  171----> 0------> 137---->
2nd splash animation:  169  170  171  172
Other 'sea' map tiles:                    0    1   137  138

  For landscapes with only one ground surface ("Ice"), the normal solution
seems to be to set both splash animations to be the same. You can also set
any unwanted second splash triggers to 255, which is an impossible tile
number.

  If you want your map tiles to be indestructible (as on "Cyber" levels),
then none of the animations data is relevant (but SFToSpr will still check
it). This is unavoidable since no map tiles set can be intrinsically
impervious - this behaviour is specified in the mission data.

4.9 Batch operations
    ----------------
  To set up a batch operation, drag a directory or application to the
SFToSpr icon. A save dialogue box with four radio buttons will appear.

  If the 'SF3000 to sprite' option is set then any SFSkyPic, SFSkyCol or
SFMapGfx files encountered within the input directory will be converted to
sprite files (with metadata embedded as 'extension data').

  If the 'Extract images' option is set then only bitmaps will be extracted
from any SFSkyPic, SFSkyCol or SFMapGfx files encountered within the input
directory; these will be output in sprite files.

  If the 'Extract data sets' option is set then only metadata will be
extracted from any SFSkyPic, SFSkyCol or SFMapGfx files encountered within
the input directory; this will be output as CSV files.

  If the 'Sprite to SF3000' option is set then any sprite files encountered
within the input directory will be converted to SFSkyPic, SFSkyCol or
SFMapGfx files, depending on the dimensions of the sprites contained therein.
Those that contain no suitable sprites will be silently ignored but an error
will be reported if a file contains a mixture of sprite sizes, or does not
have any embedded metadata.

  To overwrite files in the input directory (probably unwise) just click the
'Scan' button or press the Return key. You can set a different output
location by editing the file path or dragging the directory icon to a
directory display of your choice.

  The input directory (and all sub-directories in the hierarchy) will be
scanned, any graphics files that match the specified search criteria will be
processed and output files written in the designated directory. Any
irrelevant files will be ignored.

  The progress of the batch operation can be monitored and controlled via a
progress window that is similar to that used for Filer operations on groups
of files. The "Abort" button will terminate the batch operation, whereas the
"Pause" button only stops it temporarily. In the latter case, SFToSpr will
wait for you to click the "Continue" button before restarting.

  Errors during scanning of the directory structure will produce an extended
progress window with an error message and four buttons labelled "Abort",
"Skip", "Retry" and "Restart". "Abort" cancels the batch operation. "Skip"
ignores the offending file and continues. "Retry" will attempt to process
the file again. "Restart" will start the scan again from the beginning.

4.10 Windows submenu
     ---------------
  A 'Windows' submenu of the icon bar menu lists all windows and dialogue
boxes belonging to SFToSpr. Clicking on a menu entry will bring the
corresponding window to the front of the stack. To bring all SFToSpr windows
to the front, click SELECT on the icon bar icon.

-----------------------------------------------------------------------------
5   Error messages and warnings
    ===========================

"No embedded animations data."

  During a batch conversion from sprite to SF3000, a sprite file has been
  encountered that appears to contain tile graphics but does not contain any
  embedded animations data for inclusion in a SFMapGfx file.

"Please drag this icon to a directory display, to set the output location."

  You dragged the directory icon from an 'Output to' dialogue box to another
  application rather than a directory display. This is not a valid output
  destination for a batch operation.

"Mixed sprite sizes; unable to determine whether to create a SFMapGfx,
SFSkyPic or SFSkyCol file."

  SFToSpr cannot determine what type of SF3000 graphics file to create from a
  an input file because it contains a mixture of sprites of different sizes.

"No suitably named sprites of valid format and dimensions in this file."

  An input sprite file contains no sprites that would be valid as sky
  pictures or map graphics. This error is suppressed during a batch
  operation.

"Some animation frames or triggers were forced inside the valid range."

  This warning may be displayed upon opening a 'Save map graphics as'
  dialogue box, or when a CSV file is dragged to the same dialogue box.
  Animation frames should be between 0 and the last tile number, which
  may not be true if sprites were deleted from the input file. Trigger
  values should be between 0 and 255.

"Your 2nd splash triggers do not include the splash animation itself. You
may get unusual effects."

  Usually the second splash triggers should include the tile numbers used
  for the second splash animation. You may ignore this warning, but if in
  doubt then re-read section 4.8 of this manual "Map tile animations".

"Some paint offsets were forced inside the normal range."

  This warning is given when a CSV file containing rogue values is dragged
to the 'Save sky pictures as' dialogue box. Paint offsets (the first two
fields of the 1st and 2nd records) should be between -36 and 0.

-----------------------------------------------------------------------------
6   Command line options
    ====================

  Some options are only available as parameters to the command that invokes
the application's !RunImage file. Parameters may be specified in any order
and are not case sensitive.

  The switch '-multi' causes the 'Multiple save boxes' menu option to be set
when the application starts up.

  The switch '-quit' will cause the application to quit immediately after
having decompressed any files specified on the command line. This is
intended for use with Alias$@RunType so that graphics files may be displayed
without the application taking up permanent residence on the icon bar (though
this is not the default behaviour).

  The parameter '-timeslice' (followed by a decimal number) sets the
granularity of task switching, in centiseconds. It is analogous to
TaskWindow's '-nice' parameter: High values will cause SFToSpr to 'hog' the
computer, making the desktop unresponsive. Low values will make multitasking
very smooth but SFToSpr will run at lower priority compared to other tasks.
The default value of 10cs means that FednetCmp should compete on a level
playing field with any TaskWindows running.

  Any other parameters not preceded by '-' will be treated as paths of
SF3000 graphics files to be opened.

-----------------------------------------------------------------------------
7   Data formats
    ============

7.1 Compression format
    ------------------
  The first 4 bytes of a compressed file give the expected size of the data
when decompressed, as a 32 bit signed little-endian integer. Gordon Key's
file decompression module 'FDComp', which is presumably normative, rejects
input files where the top bit of the fourth byte is set (-ve values).

  Thereafter, the compressed data consists of tightly packed groups of 1, 8
or 9 bits without any padding between them or alignment with byte boundaries.
A decompressor must deal with two main types of chunk: The first (load a
byte) consists of 1+8 bits, and the second (copy data within output buffer)
consists of 1+9+8 or 1+9+9 bits.

The type of each chunk is determined by whether its first bit is set:

0.   Decode the next 8 bits of the input file (0-255) and write them as a
   byte at the current output position. The fact that this directive requires
   9 bits to represent 8 bits of information explains the inflation that can
   occur when attempting to compress random data.

1.   Decode the next 9 bits of the input file, which give an offset (0-511)
   within the data already decompressed, relative to a point 512 bytes behind
   the current output position. If this offset is greater than or equal to
   256 (i.e. within the last 256 bytes written) then decode the next 8 bits,
   which give the number of bytes (0-255) to be copied to the current output
   position. Otherwise, the next 9 bits give the number of bytes to be copied
   (0-511).

    If the read pointer is before the start of the output buffer then zeros
  should be written at the output position until it becomes valid again. This
  is a legitimate method of initialising areas of memory with zeros.

    A quirk of 'FDComp' is that least 1 byte is always written. That is
  probably a bug, although a well-written compressor should not insert
  directives to copy 0 bytes anyway. Note also that it isn't possible to
  replicate the whole of the preceding 512 bytes in one operation.

7.2 Sky colours file
    ----------------
  Sky colour files are stored in a compressed format (see above). The table
below shows the layout of the decompressed data, which always totals 512
bytes.

Offset  Data
+0      Render offset (signed word; 0 to 2048)
+4      Stars plot height (signed word; -32768 to 2048)
+8...   Sky data (126 patterns) :
  +8    Pattern 1 (4 pixels, 8 bits per pixel)
  +12   Pattern 2
  +16   Pattern 3...
  +508  ...Pattern 126

  Each quad-pixel pattern is tiled across the full width of the screen, and
also vertically as many times as is necessary to 'stretch' that colour band
to the desired height. On alternate lines the pattern is rotated left by one
pixel, to avoid the ugly vertical stripes that would otherwise result. The
default RISC OS 256 colour palette is assumed.

7.3 Sky pictures file
    -----------------
  Sky pictures are stored in a compressed format (see above). The table below
shows the layout of the decompressed data.

Offset  Data
+0      Last image number in file (signed word; 0 or 1)
+4      Horizontal paint offset for image 0 (signed word; -36 to 0)
+8      Vertical     "     "     "    "   " (signed word; -36 to 0)
+12     Horizontal paint offset for image 1
+16     Vertical     "     "     "    "   "
+20     Offset to image 0 word-aligned bitmap (unsigned word)
+24        "   "    "   " non-aligned    "
+28     Offset to image 1 word-aligned   "
+32        "   "    "   " non-aligned    "

  The fact that only four words of the header are allocated for paint offsets
effectively rules out files that contain more than 2 images, as does the fact
that SF3000 loads sky pictures data into a fixed-length buffer of 5,248
bytes.

  Usually, the image bitmaps are stored directly after the header (36 bytes
from the start of the file). Each one is 36 by 36 pixels, 8 bits per pixel,
1,296 bytes long. No opacity or palette data is included in the file; the
default RISC OS palette is assumed. A word-aligned bitmap always has two
columns of black pixels on its right side [*]. The non-aligned bitmap for the
same image is identical, but offset to the right by two pixels (with two
columns of black on its left side). SF3000 chooses the aligned or non-aligned
version of an image to accelerate drawing.

[* Actually, image 1 in the 'Alien' sky pictures file has coloured pixels
down the right edge of its non-aligned bitmap. In the game, these pixels
appear and disappear depending on the horizontal position of the image! The
validation code used by SFToSpr 'knows' about this and allows it as a special
case, but the extra pixels are inevitably chopped off when the image is
converted to a sprite.]

7.4 Map graphics file
    -----------------
  Map graphics sets are stored in a compressed format (see above). The table
below shows the layout of the decompressed data.

Offset  Data
+0      Last tile number in file (signed word; 0 to 254)
+4      1st frame of standard animation (tile no. 0 to 254)
+5      2nd   "   "      "        "
+6      3rd   "   "      "        "
+7      4th   "   "      "        "
+8      1st frame of alternative animation (tile no. 0 to 254)
+9      2nd   "   "        "         "
+10     3rd   "   "        "         "
+11     4th   "   "        "         "
+12     Trigger for alternative animation (first of a pair of tile nos.)
+13        "     "       "          "
+14        "     "       "          "
+15        "     "       "          "
+16...  Tile 0 bitmap
+272...  "   1   "
+528...  "   2   "
...etc

  Tile numbers must be between 0 and 254, because 255 is often given a
special interpretation (e.g. 'no map overlay here'). In practice, the fact
that SF3000 loads map graphics data into a fixed-length buffer of 49,168
bytes rules out files that contain more than 192 tiles.

  The tile graphics are stored 'upside-down' relative to the way that they
are plotted in the game. Each tile bitmap is 16 by 16 pixels, 8 bits per
pixel, 256 bytes long. No opacity or palette data is included in the file;
the default RISC OS palette is assumed.

-----------------------------------------------------------------------------
8   File types
    ==========

  The file types used by SF3000 are highly non-official. Presumably they
thought that this wouldn't matter for files used internally in the game. I
already know of some clashes (none serious) with other file types, but I
can't really alter them retrospectively.

Type  Name     Contents
----  ----     --------
&404  SFSkyCol SF3000 compressed sky colours.
&406  SFSkyPic SF3000 compressed sky pictures set.
&407  SFMapGfx SF3000 compressed map tile graphics set.
&DFE  CSV      Comma separated values; possibly animations data or paint
               offsets for sky pictures.

-----------------------------------------------------------------------------
9   Program history
    ===============

  (For really ancient history, refer to the text file 'Ancient' inside the
application directory.)

3.80 (18 Nov 2006) ----------------------------------------------------------
   Can now decode and create SF3000 sky colours files, which it deals with
    at a lower level than SFSkyEdit.

3.81 (25 Jun 2009) ----------------------------------------------------------
   Added mechanism for using Fortify to find memory leaks.
   Minor changes to code for handling CSV files dropped on save dialogue
    boxes.
   Reduced duplication between the code used for dealing with file icons
    dragged from a directory display and from another application's save
    dialogue box.
   Now gives a more helpful error report if the user drags a directory from
    another application to SFToSpr's icon on the icon bar (which still isn't
    supported).
   Linked with RISCOS Ltd's generic stubs library (previous version
    was accidentally released with an undocumented dependency upon a version
    of the shared C library which supports APCS-32).
   Documented the decompression algorithm here.

3.82 (30 Aug 2009) ----------------------------------------------------------
   All command-line arguments are now parsed together after initialisation,
    rather than only the input file names. Syntax checking is more stringent:
    switches must now be specified before file names.
   Errors when dealing with activation of the 'Quit' button in the query
    dialogue box displayed during desktop shutdown are now treated as fatal.
   Simplified the implementation of RAM transfer: it isn't necessary to
    disable budging of the flex heap (which prevents expansion of the regular
    heap) between delivery of one SaveAs_FillBuffer event and the next, or
    the final SaveAs_SaveCompleted.
   Fixed bugs that would have caused an abort on data transfer after a
    Sprite file or directory had been dragged to the iconbar icon if an error
    prevented creation of the output save box.
   Attempted to improve recovery from errors (especially in low memory
    scenarios) when reacting to mouse clicks on buttons in a progress window.
   The core bitmap conversion routines and some generic utility functions
    have migrated to CBLibrary for clarity and to allow reuse in other
    software.
   Deleted dead code for parsing the esoteric text-based format in which map
    tile animations were saved before I switched to CSV format in v3.70.
   Reduced the decompressed executable size further from 76200 to 74192
    bytes by substituting data for code and hand-optimising.

3.83 (15 Sep 2009) ----------------------------------------------------------
   No longer responds to ADJUST clicks on the icon bar ("..make Adjust do
    nothing rather than duplicating the functionality of Select..." - PRM
    vol.3 ch.53).
   Rewrote some of the interactive help messages.
   Now utilises a new CBLibrary function to set file types instead of
    calling _kernel_osfile() directly.
   A binary search is now used to find which initialisation function to call
    (if any) for the template named in a Toolbox_ObjectAutoCreated event.
   Stopped using reserved identifiers (those starting with an underscore
    followed by a capital letter).
   Reduced the decompressed executable size even further to 73240 bytes by
    various means.

3.84 (28 Jun 2010) ----------------------------------------------------------
   Specified the appropriate switches to prevent the Norcroft C compiler
    from generating unaligned memory accesses incompatible with ARM v6 and
    later (for RISC OS on BeagleBoard).
   Expunged references to type and function names deprecated in release 34
    of CBLibrary.
   Gave names to many 'magic' values (numeric constants). Anonymous
    enumerations are now used in preference to macro definitions.
   Use 'flex_ptr' more widely to reduce the number of casts to that type.
   Removed references to CBLibrary header file "TboxBugs.h". Kept the
    work-arounds for non-delivery of Quit_DialogueCompleted events and
    failure to reassign input focus after closing a transient window.
   Removed some superfluous casts from 'void *' to other pointer types.
   Reworded some label text, interactive help and the advice appended when
    reporting error messages to the user.

3.85 (09 Jan 2011) ----------------------------------------------------------
   Linked against release 40 of CBLibrary, in which the compression and
    decompression code have been rewritten from scratch.
   Fixed a memory leak (of the input buffer) if an error occurs while
    loading a file during a batch operation.
   Sets the type of files created during a batch operation only when all
    of the data has been written, instead of every time it is interrupted to
    poll the event library.

3.86 (28 Jan 2011) ----------------------------------------------------------
   Linked against release 42 of CBLibrary, in which the speed of compression
    and error detection during decompression have been improved.

3.87 (13 Feb 2011) ----------------------------------------------------------
   Updated the amount of free memory required to start the application from
    92K to 128K (of which 96K is assigned to the application memory slot).

3.88 (03 Feb 2018) ----------------------------------------------------------
   Linked against release 54 of CBLibrary, which provides new string buffer
    and directory iterator objects, and a generic double-linked list.
   Switched to signed integer types for all data words in a sprite area and
    added checks for the count of sprites being negative (clamped to 0).
   Much code refactoring: reduced use of 'goto', heap block addresses are
    now used in preference to toolbox object IDs, and generic savebox-related
    code is now implemented as a superclass to avoid code duplication.
   Removed reliance on calling the _kernel_setenv function with NULL to
    delete a variable because of a bug in early versions of the shared C
    library (including 3.75, the minimum required).
   Older saveboxes are no longer deleted upon unticking the 'Multiple
    saveboxes' option (kludgy implementation of questionable behaviour).
   Wrote unit tests to properly test error-handling paths.
   Fixed a bug where PreQuit messages were always assumed to incorporate a
    flags word, making it unpredictable whether or not desktop shutdown was
    restarted if no flags were present. That had little practical effect
    because the extra word is always present from RISC OS 3 onward.
   Simplified OS error handling by reporting errors as early as possible
    and not making subsequent code conditional unless absolutely necessary.
   Errors during parsing of command line arguments are now fatal.
   Successfully creating a top-level output directory is now considered
    sufficient to signal success via the SaveAs_FileSaveCompleted method.
   Created an alternative makefile for use with GNU Make and the GNU C
    compiler.

3.89 (09 Feb 2019) ----------------------------------------------------------
   The input buffer is no longer freed during a batch operation unless
    loading failed or conversion succeeded. This is necessary for safe retry.
   Added 'const' qualifiers to event handler function arguments.
   Updated the Makefiles to share a common list of source files and link
    with separate C libraries instead of the old monolithic CBLibrary.
   Deleted the build configuration in which OLD_SCL_STUBS was not defined.

3.90 (28 Oct 2020) ----------------------------------------------------------
   Fixed use-after-free upon abnormal termination of a batch operation.
    This could cause assertion failure in writer_flex_destroy (because the
    freed buffer's size appeared smaller than the no. of bytes written).
   Specified a list of messages of interest upon task initialization for
    improved efficiency.
   Defined a custom Toolbox event number for bringing all windows to the
    front, to allow the user interface to be reconfigured using ResEd alone.
   Deleted redundant 'extern' linkage specifiers.

3.91 (03 Dec 2020) ----------------------------------------------------------
   Linked with a bugfixed version of my streams library that cannot become
    stuck in an infinite loop when writing to a compressed file.
   Linked with a bugfixed version of SF3KLib so that the actual sprite name
    is reported (instead of the expected name prefix) when an input sprite
    does not match the required format.

3.92 (10 Dec 2020) ----------------------------------------------------------
   Linked with a bugfixed version of my streams library that cannot produce
    truncated output when writing to a compressed file. (Previous attempted
    bugfix had this bad side-effect.)
   Removed the 'New format sprites' option. SFToSpr now always creates
    sprites with an old type specifier (screen mode 13) for the widest
    compatibilty. Moved the remaining ('Multiple save boxes') option to the
    top level of the iconbar menu.
   No longer utilises SpriteExtend 0.99 to verify sprite areas because the
    format conversion code is now OS-agnostic.
   Uses abstract data streams for input and output as required by the
    'Loader3' component in release 58 of CBLibrary. This entailed a rewrite
    of the core format conversion code (with the side-effect that SF3KLib is
    no longer a link-time dependency).
   Eliminated pre-declaration of 'static' functions where possible.
   Downgraded the Draggable gadget template version for compatibility with
    ROOL's ResEd Window Editor (to avoid "Bad size 60 for gadget type 640").
   Save dialogue boxes are now explicitly hidden after a successful save
    (because ROOL's version of SaveAs doesn't do that automatically).

3.93 (01 Aug 2022) ----------------------------------------------------------
   Fix missing 'return' statement in the main() function of a test program.
   Use a new library function to remove all event handlers and delete a
    Toolbox object.
   Intercept #include of library headers (for debugging purposes) using
    local files of the same name, which requires use of "" instead of <>.
   Prefer to minimise declaration scope.
   Use CONTAINER_OF() in preference to assuming the layout of structs.
   Use bit fields for a struct with many Boolean members.

3.94 (02 Aug 2022) ----------------------------------------------------------
   Close the output (and input) files before opening the temporary sprite
    file when a Star Fighter 3000 graphics file has been double clicked in a
    directory display.
   Check the return value of fclose() for error after writing a temporary
    sprite file.

-----------------------------------------------------------------------------
10  Compiling the program
    =====================

  If you did not receive source code with this program then you can download
it from http://starfighter.acornarcade.com

  This program incorporates code from several C libraries created by the same
author: CBLibrary, CBOSLib, CBUtilLib, SF3KLib and GKeyLib. Source code for
those libraries is available at http://starfighter.acornarcade.com/mysite/

  To compile and link the program you will also require ISO 'C' (9899:1999)
library headers, stubs for the shared C library, and the flex, toolbox, event
and wimp libraries supplied with the Acorn C/C++ Development Suite. You must
ensure that the library directories clib, tboxlibs and flexlib are on your
C$Path, otherwise the compiler won't be able to find the required headers.

  Two make files are supplied:

   'Makefile' is intended for use with Acorn Make Utility (AMU) and the
    Norcroft C compiler supplied with the Acorn C/C++ Development Suite.
   'GMakefile' is intended for use with GNU Make and the GNU C Compiler.
    I have used it experimentally to compile but not to link the program.

  The APCS variant specified for the Norcroft compiler is 32 bit for
compatibility with ARMv5 and fpe2 for compatibility with older versions of
the floating point emulator. Generation of unaligned data loads/stores is
disabled for compatibility with ARMv6. When building the code for release,
it is linked with RISCOS Ltd's generic C library stubs ('StubsG').

-----------------------------------------------------------------------------
11  Licence and Disclaimer
    ======================

  This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public Licence as published by the Free
Software Foundation; either version 2 of the Licence, or (at your option)
any later version.

  This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licence for
more details.

  You should have received a copy of the GNU General Public Licence along
with this program; if not, write to the Free Software Foundation, Inc.,
675 Mass Ave, Cambridge, MA 02139, USA.

-----------------------------------------------------------------------------
12  Credits
    =======

  SFToSpr was designed and programmed by Christopher Bazley.

  Credit goes to David O'Shea and Keith McKillop for working out the
Fednet compression algorithm. David wrote a DeComp module for use with the
Stunt Racer track designer, which early versions of SFToSpr relied upon.

  Olaf Krumnow and Herbert zur Nedden of the German Archimedes Group wrote
the ResFind program I use to find the correct resources for different
languages.

  Thanks to Richard Wilson for writing 'NoDisc', a utility to remove the
disc protection from SF3000. None of my early work with the game would
have been possible without this.

  At the early stages of development, my sister Harriet did some beta-
testing for me.

  Thanks to the denizens of comp.sys.acorn.programmer for their advice - in
particular Kevin Bracey, John Duffell, Andrew Hodgkinson, Richard Murray and
Stewart Brodie.

  The excellent bands Pulp and Queen, and the film music of John Williams
and David Arnold probably also deserve a mention for keeping me sane (mostly
;-)) through the long nights (I haven't slept for 36hrs as I type this!)

  The application name "SFToSpr" (including associated sprites/system
variables) has been officially registered with RISCOS Ltd.

  The game Star Fighter 3000 is  FEDNET Software 1994, 1995.

-----------------------------------------------------------------------------
13  Contact details
    ===============

  Feel free to contact me with any bug reports, suggestions or anything else.

  Email: mailto:cs99cjb@gmail.com

  WWW:   http://starfighter.acornarcade.com
