Star Fighter 3000 to Wavefront convertor

© Christopher Bazley, 2016

Version 0.07 (21 Apr 2020)

Download SF3KtoObj and SF3KtoMtl (96  KB Zip archive, includes source code).

Download the game's object meshes in .obj and .mtl format (104  KB Zip archive).

Introduction and Purpose

These two command-line programs can be used to convert object meshes and colour palettes belonging to the 32-bit Acorn RISC OS game Star Fighter 3000 from their original format into the simple object geometry and material formats developed by Wavefront for their Advanced Visualizer software. Wavefront OBJ format is a de-facto standard for 3D computer graphics and it has the advantage of being human-readable.

Different missions in the game use different palettes, for example 'Strategic Bomber Test' (M9) colours the player's ship in yellow, ruby and scarlet instead of its normal livery of fern green.

The colour and other visual properties of objects are defined separately from the object geometry (OBJ) file in a companion file known as a material library (MTL) file. The supplied MTL file defines all of the colours in the default RISC OS 256-colour palette as named materials, assuming a constant colour illumination model (no texture map, ambient or specular reflectance). Alternatively, the game's mission-specific palettes can be converted to MTL files.


The following screeenshots show the object mesh for the Fednet mothership imported into the Open 3D Model Viewer.

Here are the converted object geometry and material library files: mothership.obj and sf3k.mtl

Fednet mothership in the Open 3D Model Viewer Fednet mothership in the Open 3D Model Viewer


The supplied executable files will only work on RISC OS machines. They have not been tested on any version of RISC OS earlier than 4, although they should also work on earlier versions provided that a suitable version of the 'SharedCLibrary' module is active. They should be compatible with 32 bit versions of RISC OS.

You will obviously require a copy of the game 'Star Fighter 3000' from which to rip the graphics. It is free to download (as a 1195  KB Zip archive).

Object definition files can be found inside the !Star3000 application, in !Star3000.LandScapes.Graphics; palette files can be found in !Star3000.LandScapes.Palette. Depending on your version of the game, the LandScapes directory might be inside another named 'Disc2'.

Quick Guide

Ensure that the !Star3000 application has been 'seen' by the Filer, so that the system variable Star3000$Dir has been set.

Hold down the Shift key and double-click on the !Star3000 application to open it.

Set the current selected directory to that containing the 'SF3KtoObj' program. On RISC OS 6, that can be done by opening the relevant directory display and choosing 'Set work directory' from the menu (or giving the directory display the input focus and then pressing F11).

Press Ctrl-F12 to open a task window and then invoke the conversion program using the following command:

*SF3KtoObj -list <Star3000$Dir>.Landscapes.Graphics.Earth1

This should list all of the object definitions within the compressed graphics file 'Earth1'. One of those should be named 'player', which is the definition of the 'Predator Mk-IV' combat fighter normally flown by the player.

To convert the 'Predator Mk-IV' object mesh into a Wavefront OBJ file named 'player/obj', use the following command:

*SF3KtoObj -name player -palette <Star3000$Dir>.LandScapes.Palette.Default <Star3000$Dir>.LandScapes.Graphics.Earth1 player/obj

(A forward-slash rather than a dot is used to separate file names from file extensions on RISC OS. This is merely a convention; RISC OS instead stores the type of files in hidden metadata.)

The -name argument selects which object is converted and the -palette argument selects which of the five palettes supplied with the game is used for the conversion. The 'Default' palette applies training colours (fern green with teal and blue stripes) to the 'Predator Mk-IV'.

By varying the arguments to the 'SF3KtoObj' program, any of the other files in the !Star3000.LandScapes.Graphics directory can be converted to Wavefront OBJ format.

Common usage information

Command line syntax

The basic syntax of both programs is the same, as summarised below. They have two principle modes of operation: single file mode and batch processing. All switches are optional, but some are incompatible with each other (e.g. -batch with -outfile). Switch names may be abbreviated provided that doing so does not make the command ambiguous.


SF3KtoObj [switches] [<input-file> [<output-file>]]


SF3KtoObj -batch [switches] <file1> [<file2> .. <fileN>]

Input and output

Process a batch of files (see above)
Input is uncompressed raw data
-outfile <file>
Write output to the named file instead of stdout

Single file mode is the default mode of operation. Unlike batch mode, the input and output files can be specified separately. An output file name can be specified after the input file name, or before it using the -outfile parameter.

If no input file is specified, input is read from 'stdin' (the standard input stream; keyboard unless redirected). If no output file is specified, output is written to 'stdout' (the standard output stream; screen unless redirected).

All of the following examples read input from a file named 'foo' and write to a file named 'bar':

*SF3KtoObj foo bar

*SF3KtoObj -outfile bar foo

*SF3KtoObj -outfile bar <foo

*SF3KtoObj foo >bar

Under UNIX-like operating systems, output can be piped directly into another program.

Search for a named object in a compressed graphics file named 'foo':

SF3KtoObj foo | grep -i 'bit_10'

Batch mode is enabled by the switch -batch. In this mode, multiple files can be processed using a single command. The output is always saved to a file with a name derived from the input file's name, which means that programs cannot be chained using pipes. At least one file name must be specified.

Convert compressed graphics files named 'foo', 'bar' and 'baz' to Wavefront OBJ files named 'foo/obj', 'bar/obj' and 'baz/obj':

*SF3KtoObj -batch foo bar baz

(If the program were correctly ported to a Unix-like system then the output file names would instead be 'foo.obj', 'bar.obj' and 'baz.obj'.)

By default, all input is assumed to be compressed. The switch -raw allows uncompressed input, which may be useful if input has already been decompressed.

It isn't possible to mix compressed and uncompressed input, for example by using compressed graphics data with an uncompressed palette file.

Getting diagnostic information

Show the total time for each file processed
-verbose or -debug
Emit debug information (and keep bad output)

If either of the switches -verbose and -debug is used then the two programs emit information about their internal operation on the standard output stream. However, this makes them slower and prevents output being piped to another program.

If the switch -time is used then the total time for each file processed (to centisecond precision) is printed. This can be used independently of -verbose and -debug.

When debugging output or the timer is enabled, you must specify an output file name. This is to prevent the MTL or OBJ format output being sent to the standard output stream and become mixed up with the diagnostic information.

SF3KtoObj usage information

Object selection

-index N
Object number to convert or list (default is all)
-first N
First object number to convert or list
-last N
Last object number to convert or list
-type G|B|S
Object type to convert or list (default is all)
-name <name>
Object name to convert or list (default is all)

The contents of a graphics file can be filtered using the -index or -first and -last parameters to select a single object or range of objects to be processed. Using the -index parameter is equivalent to setting the first and last numbers to the same value. The lowest object number is 0.

A file can also be filtered using the -type and -name parameters to select single objects or types of object to be processed. Any filter specified applies when listing object models as well as when converting them.

If no range of object numbers, type or name is specified then all objects defined in the input file are processed.

If an object type is specified then only objects of the given type are processed. The three types of object are [S]hip, [G]round and [B]it.

Convert all ship objects in file 'Earth1':

*SF3KtoObj -type S <Star3000$Dir>.LandScapes.Graphics.Earth1

Convert all ground objects in file 'CyberZ':

*SF3KtoObj -type G <Star3000$Dir>.LandScapes.Graphics.CyberZ

If an object index is specified then the specified number of object definitions are skipped before processing a single object with the given index (counting upwards from 0).

Convert the first object of any type in file 'Earth2', outputting to the screen:

*SF3KtoObj -index 0 <Star3000$Dir>.LandScapes.Graphics.Earth2

If both an object index and an object type are specified then the index is interpreted differently: objects of other types are not counted when searching for the object with the given index.

Specifying both -type and -index is usually more useful than only specifying -index because the game only treats the order of object definitions as significant relative to other objects of the same type.

Convert the eighth ground object in file 'Earth2' (see below for object numbering):

*SF3KtoObj -type G -index 7 <Star3000$Dir>.LandScapes.Graphics.Earth2

Convert the fifteenth ship object in file 'Earth2', outputting to the screen:

*SF3KtoObj -type S -index 14 <Star3000$Dir>.LandScapes.Graphics.Earth2

If an object name is specified then the single object of the given name is processed (provided that it falls within the specified range of object numbers, if any).

Convert the mothership object in file 'Warrior' (see below for object naming):

*SF3KtoObj -name mothership <Star3000$Dir>.LandScapes.Graphics.Warrior

Convert one of the two hangar objects in file 'Warrior', outputting to the screen:

*SF3KtoObj -name hangar_2 <Star3000$Dir>.LandScapes.Graphics.Warrior

Ground objects

Number Name Object
0 none None
1 gun_1 Ground gun
2 gun_2 Ground gun
3 gun_3 Ground gun
4 sam_1 Surface-to-air missile launcher
5 sam_2 Surface-to-air missile launcher
6 sam_3 Surface-to-air missile launcher
7 hangar_1 Hangar
8 hangar_2 Hangar

Ship objects

Number Name Object
0 player Player's ship
1 fighter_1 Fighter
2 fighter_2 Fighter
3 fighter_3 Fighter
4 fighter_4 Fighter
5 three_coin Bonus coin (3 credits)
6 ten_coin Bonus coin (10 credits)
7 life_coin Bonus coin (extra life)
8 fifty_coin Bonus coin (50 credits)
9 twenty_coin Bonus coin (20 credits)
10 atg_coin Bonus coin (10 A-T-G missiles)
11 ata_coin Bonus coin (10 A-T-A missiles)
12 damage_coin Damage coin
13 big_ship_1 Big ship
14 mothership Mothership
15 big_ship_2 Big ship
16 atg_missile A-T-G missile
17 ata_missile A-T-A missile
18 mine Aerial mine
19 bomb Freefall bomb
20 parachute Parachute
21 satellite Satellite
22 dock Docking bay

Listing and summarizing objects

List objects instead of converting them
Summarize objects instead of converting them

If the switch -list is used then SF3KtoObj lists object definitions found in the specified input file(s) instead of converting them to Wavefront OBJ format. Only object models matching any filter specified using the -index, -first, -last, -type and -name parameters are listed.

No output file can be specified because no OBJ-format output is generated and the object list or summary is always sent to the standard output stream.

List all object definitions in file 'Chemical':

*SF3KtoObj -list <Star3000$Dir>.LandScapes.Graphics.Chemical

List all ship objects in file 'CyberZ':

*SF3KtoObj -list -type s <Star3000$Dir>.Graphics.CyberZ

Output is a table with the following format:

Index  Type    Index  Name          Verts  Faces      Offset        Size
    0  Bit         0  bit_0             8      6         100         168

If the switch -summary is used then SF3KtoObj summarizes object definitions found in the specified input file(s) instead of converting them to Wavefront OBJ format. This switch can be used in conjunction with -list, in which case the summary is displayed after the list.

Summarize all object definitions in file 'Earth1':

*SF3KtoObj -summary <Star3000$Dir>.LandScapes.Graphics.Earth1

Output is a list of totals in the following format:

Found 69 object definitions, comprising:
  34 Ground objects
  12 Bit objects
  23 Ship objects

Palettes and materials

-mtllib name
Specify a material library file (default sf3k.mtl)
-palette name
Specify a palette file in which to look up physical colours (default is none)
Output readable material names (needs -palette)
Assign false colours for visualization

If no palette file is specified then SF3KtoObj emits 'usemtl' commands that refer to logical colours by derived material names such as 'colour_31'. The advantage of this mode of operation is that palette swapping can be done simply by amending the name of the MTL file referenced by the OBJ file.

Convert the player's ship in file 'Earth1', outputting logical colour numbers to the screen:

*SF3KtoObj -type s -index 0 <Star3000$Dir>.LandScapes.Graphics.Earth1

g player player_0
usemtl colour_302
f  23 22 21 44
usemtl colour_304
f  23 24 1 22
f  44 21 20 43
usemtl colour_316
f  49 46 47 48

If a palette file is specified then SF3KtoObj uses it to look up the physical colour associated with each logical colour. An advantage of doing this look-up during conversion is that all OBJ files can use the same MTL file, which need only define the standard 256 RISC OS colours.

Convert the player's ship in file 'Earth1', specifying palette file 'RedShip' and outputting physical colour numbers to the screen:

*SF3KtoObj -type s -index 0 -palette <Star3000$Dir>.LandScapes.Palette.RedShip <Star3000$Dir>.LandScapes.Graphics.Earth1

g player player_0
usemtl riscos_119
f 23 22 21 44
usemtl riscos_30
f 23 24 1 22
f 44 21 20 43
usemtl riscos_200
f 49 46 47 48

If the switch -human is used then SF3KtoObj goes one step further and refers to physical colours by human-readable material names such as 'black_0'. This can only be enabled if a palette file is specified.

Convert the player's ship in file 'Earth1', outputting human-readable colour names to the screen:

*SF3KtoObj -type s -index 0 -human -palette <Star3000$Dir>.LandScapes.Palette.RedShip <Star3000$Dir>.LandScapes.Graphics.Earth1

g player player_0
usemtl peridot_3
f  23 22 21 44
usemtl crimson_2
f  23 24 1 22
f  44 21 20 43
usemtl honolulublue_0
f  49 46 47 48

By default, SF3KtoObj emits a 'mtllib' command which references 'sf3k.mtl' as the material library file to be used when drawing objects; this is the same as the name of the supplied MTL file.

An alternative material library file can be specified using the switch -mtllib. The named file is not created, read or written by SF3KtoObj.

False colours can be assigned to help visualise boundaries between polygons, especially between coplanar polygons of the same colour. This mode, which is mainly useful for debugging, is enabled by specifying the switch -false.

When false colours are enabled, the logical colours in the input file are ignored. If a palette file was specified then its content is ignored too.


-frame N
Animation frame to convert (default is 0)

Logical colours in the range 256..283 are animated every frame and those in the range 284..299 are animated every second frame. Groups of four physical colours are rotated in the palette, giving a total of 11 animations. The faster animations are used for spacecraft engines and lights; the slower ones for ground installations.

Certain objects include sets of vertices that rotate anti-clockwise (as viewed from above) at a rate of 5.625 degrees or 1/64th of a full circle per frame. An example is the 'hangar_2' object in files 'Earth1', 'Earth2' and 'Warrior'.

If the parameter -frame is used then the following argument controls which animation frame is converted. The default value is 0, which is the first frame. If a palette file was specified then different physical colours are looked up in the palette; either way, the 'usemtl' commands in the output are likely to differ. Rotating vertices are also affected.

Convert animation frame 0 of a radar installation in file 'Earth1':

*SF3KtoObj -name ground_26 -frame 0 <Star3000$Dir>.LandScapes.Graphics.Earth1

v 16.000000 16.000000 -128.000000
v 16.000000 -16.000000 -128.000000
v 0.000000 0.000000 -128.000000
# Following vertices rotate
v 16.000000 -16.000000 -128.000000
v 16.000000 16.000000 -128.000000
v -16.000000 16.000000 -128.000000

Convert animation frame 1 of the same object:

*SF3KtoObj -name ground_26 -frame 1 <Star3000$Dir>.LandScapes.Graphics.Earth1

v 16.000000 16.000000 -128.000000
v 16.000000 -16.000000 -128.000000
v 0.000000 0.000000 -128.000000
# Following vertices rotate
v 14.354681 -17.491230 -128.000000
v 17.491230 14.354681 -128.000000
v -14.354681 17.491230 -128.000000


Clip overlapping coplanar polygons

Some objects are liable to suffer from a phenomenon known as "Z-fighting" if they are part of a scene rendered using a depth (Z) buffer. It is caused by overlapping faces in the same geometric plane and typically manifests as a shimmering pattern in a rendered image. Essentially two or more polygons occupy the same points in 3D space.

The game uses painter's algorithm to ensure that overlapping objects are drawn correctly (drawing more distant objects before nearer ones), instead of using a depth buffer. It also draws the polygons of each object in a predictable order, which allows overlapping polygons to be used as decals (e.g. as doors and windows on buildings).

If the switch -clip is used then the rearmost of two overlapping polygons is split by dividing it along the line obtained by extending one edge of the front polygon to infinity in both directions. This process is repeated until no two edges intersect. Any polygons that are fully hidden (typically behind decals) are deleted.

The following diagrams illustrate how one polygon (B: 1 2 3 4) overlapped by another (A: 5 6 7 8) is split into five polygons (B..F) during the clipping process. The last polygon (F) is then deleted because it duplicates the overlapping polygon (A).

Output of faces

Split complex polygons into triangle fans
Split complex polygons into triangle strips
Use negative vertex indices

The Wavefront OBJ format specification does not restrict the maximum number of vertices in a face element. Nevertheless, some programs cannot correctly display faces with more than three vertices. Two switches, -fans and -strips, are provided to split complex polygons into triangles.

Original Triangle fans Triangle strips
f 1 2 3 4 5 6
f 1 2 3
f 1 3 4
f 1 4 5
f 1 5 6
f 1 2 3
f 6 1 3
f 6 3 4
f 5 6 4

Vertices in a face element are normally indexed by their position in the output file, counting upwards from 1. If the output comprises more than one object definition then it can be more useful to count backwards from the most recent vertex definition, which is assigned index -1. The -negative switch enables this output mode, which allows object models to be separated, extracted or rearranged later.

Convert the mothership in file 'Earth1' with positive vertex indices:

*SF3KtoObj -type s -index 14 <Star3000$Dir>.LandScapes.Graphics.Earth1

g mothership mothership_0
usemtl colour_44
f 29 32 31 30
usemtl colour_45
f 1 2 32 29

Convert the same object with negative vertex indices:

*SF3KtoObj -type s -index 14 -negative <Star3000$Dir>.LandScapes.Graphics.Earth1

g mothership mothership_0
usemtl colour_44
f -67 -64 -65 -66
usemtl colour_45
f -95 -94 -64 -67

Hidden data

Include hidden polygons in the output
Include unused vertices in the output
Include duplicate vertices in the output

'Star Fighter 3000' groups polygons belonging to complex objects to allow it to determine more efficiently which face the camera and which do not. Complex objects have a non-zero plot type. Groups are only drawn if a surface normal designated by the plot type of the object points towards (or away from) the viewer. The surface normals to be tested must belong to polygons in group 7.

If the switch -hidden is used then SF3KtoObj outputs groups which are hidden because they are not referenced by an object's plot type definition. It does not actually compute any surface normals to determine visibility of groups.

'Star Fighter 3000' specifies vertex coordinates using logarithmic offsets from the coordinates of a previous vertex. This encoding scheme may require intermediate vertices to reach the desired coordinates. Such vertices are not referenced by polygons and therefore they are not included in the output unless the -unused switch is used.

Some object models also include two or more vertices with the same coordinates, where both vertexes are referenced by polygons. Examples include vertex 111/117 of big_ship_1 in file 'Chemical' and vertex 49/57 of fighter_3 in 'Earth1'. Such pairs of vertices are automatically merged unless the -duplicate switch is specified.

SF3KtoMtl usage information

Colour selection

-index N
Logical colour to convert (N=0..319, default all)
-first N
First logical colour to convert
-last N
Last logical colour to convert

The contents of a palette file can be filtered using the -index or -first and -last parameters to select a range of logical colours to be processed. Using the -index parameter is equivalent to setting the first and last numbers to the same value.

If no range of indices is specified then all logical colours defined in the input file are processed.

The following example converts only the last logical colour in the default palette:

*SF3KtoMtl -index 319 <Star3000$Dir>.LandScapes.Palette.Default

newmtl colour_319
# grey tint 2
Kd 0.666667 0.666667 0.666667
illum 0

Material names

Output unique physical colours as materials
Output readable material names (implies -physical)

By default, SF3KtoMtl emits one 'newmtl' command for each of the 320 logical colours, giving each a derived material name such as 'colour_31'. This mode of operation is designed to complement SF3KtoObj when invoked without a palette file. The palette can then be switched at any time by referencing a different MTL file from the OBJ file.

If the switch -physical is used then SF3KtoMtl instead uses the physical colour associated with each logical colour to generate a material name. The physical colour numbers refer to the standard RISC OS 256 colour palette. This mode of operation is designed to complement SF3KtoObj when invoked with a palette file. The palette is fixed when the OBJ file is generated.

Convert all unique physical colours in file 'FastShip':

*SF3KtoMtl -physical <Star3000$Dir>.LandScapes.Palette.FastShip

newmtl riscos_0
# black tint 0
Kd 0.000000 0.000000 0.000000
illum 0

newmtl riscos_1
# black tint 1
Kd 0.066667 0.066667 0.066667
illum 0

If the switch -human is used then SF3KtoMtl generates a human-readable material name such as 'black_0' for each unique physical colour. This switch implies -physical, which needn't be passed explicitly.

Convert all physical colours in file 'FastShip', generating human-readable material names:

*SF3KtoMtl -human <Star3000$Dir>.LandScapes.Palette.FastShip

newmtl black_0
Kd 0.000000 0.000000 0.000000
illum 0

newmtl black_1
Kd 0.066667 0.066667 0.066667
illum 0

It does not really matter which palette file is used as input to SF3KtoMtl when the switch -physical or -human is used because every game palette maps at least one logical colour to every available physical colour. SF3KtoMtl never outputs duplicate material definitions, so it always defines exactly 256 materials; one for each physical colour.

Material properties

-d N
Dissolve factor for transparency (N=0..1, default 1)
-illum N
Which illumination model to use (N=0..10, default 0)
0 Constant colour model
1 Diffuse model
2 Diffuse and specular model
3 Diffuse and specular model with ray tracing and reflection map
4 Like 3 but with the dissolve factor adjusted to simulate glass
5 Like 3 but with additional Fresnel effects
6 Diffuse and specular model with ray tracing, reflection map and refraction
7 Like 6 but with additional Fresnel effects
8 Diffuse and specular model with reflection map
9 Like 8 but with the dissolve factor adjusted to simulate glass
10 Cast shadows onto invisible surfaces

Switches for illumination models 2..9

-ks R[,G,B]
Specular reflectivity (R=0..1, G=0..1, B=0..1) Default is the same as the ambient colour. Green and blue default to red if not specified.
-ns N
Specular exponent (default 200.0)

Switches for illumination models 3..9

-sharpness N
Sharpness of reflection map (N=0..1000, default 60)

Switches for illumination models 6..7

-ni N
Optical density (N=0.001..10, default 1.0)
-tf R[,G,B]
Transmission filter (R=0..1, G=0..1, B=0..1) Default is 1.0. Green and blue default to red if not specified.

These switches are for advanced users only and map directly to commands in the output MTL file. They are best understood by reading the Wavefront documentation.

Colour names

The colour names were taken from a variety of online sources including Wikipedia articles, W3C standards, the X Window System, and the results of the web comic XKCD's colour naming survey.

On RISC OS, the default 256 colour palette is generated by using two bits of the colour index to encode each component (red, green or blue), with two additional 'tint' bits shared between all components (2+2+2+2=8 bits per pixel). Mixing white into a colour by setting tint bits increases its value (aka brightness) but reduces its saturation. Consequently the palette has a characteristic lack of saturated colours.

In natural language, the word 'purple' is used to describe many colours of the same hue and saturation but very different brightness (e.g. the X11 colours 'magenta', 'darkmagenta' and 'purple'). Consequently a weighted least-squares algorithm such as that used by the ColourTrans module is ill- suited to finding matching colour names. Normalizing the {red, green, blue} vector for each palette entry and named colour before comparing them produces better results; a weighted sum of the unit vector difference and vector length difference (70:30) ensures that the name closest to the desired brightness is still chosen.

Initially, I tried to find the named colour closest to each palette entry and discovered that tints of the same primary colour had unrelated names or the gradation from dark to bright tints was unclear. I therefore abandoned my original list of 256 colour names and instead generated names for each of the 64 fully-saturated colours (tint 0).

Colours 16, 128 and 144 are named using the short X11 names 'maroon', 'navy' and 'purple' instead of the slightly better-matching X11 names 'darkred', 'darkblue' and 'darkmagenta'. That is to avoid confusion between those colours and the even darker colours 4, 8 and 12. Colours 20 and 96 are not actual X11 colour names but were named in the same style as 'mediumblue' so that all three primaries at the same brightness have similar names.

The final colours are listed below:

Index Web T0 T1 T2 T3 Name Notes
0 #000000 black * Identical to HTML 'black'
4 #440000 darkmaroon By analogy with 'darkred'
8 #000044 darknavy By analogy with 'darkblue'
12 #440044 darkpurple By analogy with 'darkmagenta'
16 #880000 maroon * Like HTML colour #800000
20 #cc0000 mediumred By analogy with 'mediumblue'
24 #880044 tyrianpurple Like Wikipedia colour #66023c
28 #cc0044 crimson * Like X11 colour #dc143c
32 #004400 darkgreen + Like X11 colour #006400
36 #444400 darkolive Like XKCD colour #373e02
40 #004444 darkteal Like XKCD colour #014d4e
44 #444444 darkgrey + Darker than X11 'dimgray'
48 #884400 brown * Like Wikipedia colour #964b00
52 #cc4400 mahogany Like Wikipedia colour #c04000
56 #884444 cordovan Like Wikipedia colour #893f45
60 #cc4444 brickred Like Wikipedia colour #cb4154
64 #008800 green * Like HTML colour #008000
68 #448800 avocado Like Wikipedia colour #568203
72 #008844 pigmentgreen Like Wikipedia colour #00a550
76 #448844 ferngreen Like Wikipedia colour #4f7942
80 #888800 olive * Like HTML colour #808000
84 #cc8800 harvestgold Like Wikipedia colour #da9100
88 #888844 darktan Like Wikipedia colour #918151
92 #cc8844 peru * Like X11 colour #cd853f
96 #00cc00 mediumgreen By analogy with 'mediumblue'
100 #44cc00 napiergreen Like Wikipedia colour #2a8000
104 #00cc44 darkpastelgreen Like Wikipedia colour #03c03c
108 #44cc44 limegreen * Like X11 colour #32cd32
112 #88cc00 applegreen Like Wikipedia colour #8db600
116 #cccc00 peridot Like Wikipedia colour #e6e200
120 #88cc44 yellowgreen * Like X11 colour #9acd32
124 #cccc44 oldgold Like Wikipedia colour #cfb53b
128 #000088 navy * Like HTML colour #000080
132 #440088 indigo * Like X11 colour #4b0082
136 #0000cc mediumblue * Like X11 colour #0000cd
140 #4400cc violetblue Like XKCD colour #510ac9
144 #880088 purple * Like HTML colour #800080
148 #cc0088 mediumvioletred * Like X11 colour #c71585
152 #8800cc darkviolet * Like X11 colour #9400d3
156 #cc00cc deepmagenta Like Wikipedia colour #cc00cc
160 #004488 mediumelectricblue Like Wikipedia colour #035096
164 #444488 darkslateblue * Like X11 colour #483d8b
168 #0044cc royalazure Like Wikipedia colour #0038a8
172 #4444cc pigmentblue Like Wikipedia colour #333399
176 #884488 plum + Like Wikipedia colour #8e4585
180 #cc4488 mulberry Like Wikipedia colour #c54b8c
184 #8844cc lavenderindigo Like Wikipedia colour #9457eb
188 #cc44cc deepfuchsia Like Wikipedia colour #c154c1
192 #008888 teal * Like HTML colour #008080
196 #448888 dustyteal Like XKCD colour #4c9085
200 #0088cc honolulublue Like Wikipedia colour #007fbf
204 #4488cc celestialblue Like Wikipedia colour #4997d0
208 #888888 grey * Like HTML colour #808080
212 #cc8888 oldrose Like Wikipedia colour #c08081
216 #8888cc ube Like Wikipedia colour #8878c3
220 #cc88cc pastelviolet Like Wikipedia colour #cb99c9
224 #00cc88 caribbeangreen Like Wikipedia colour #00cc99
228 #44cc88 mint Like Wikipedia colour #3eb479
232 #00cccc darkturquoise * Like X11 colour #00ced1
236 #44cccc mediumturquoise * Like X11 colour #48d1cc
240 #88cc88 darkseagreen * Like X11 colour #8fbc8f
244 #cccc88 lightbeige Like Ford colour #d2d08e
248 #88cccc pearlaqua Like Wikipedia colour #88d8c0
252 #cccccc lightgrey * Like X11 colour #d3d3d3

* means that a colour has the same name as one of the standard X11 colours and closely resembles it.

+ means that a colour has the same name as one of the standard X11 colours but is significantly darker.

Program history

0.01 (02 Dec 2016)

0.02 (11 Dec 2016)

0.03 (17 Apr 2017)

0.04 (29 Aug 2018)

0.05 (31 Aug 2018)

0.06 (17 Nov 2018)

0.07 (21 Apr 2020)

Compiling the software

Source code is only supplied for the command-line programs. To compile and link the programs you will also require an ISO 9899:1999 standard 'C' library and four of my own libraries: 3dObjLib, CBUtilLib, StreamLib and GKeyLib.

Two make files are supplied:

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').

Before compiling the programs for other platforms, rename the C source and header files with .c and .h file extensions then move them out of their respective subdirectories. The only platform-specific code is the PATH_SEPARATOR and EXT_SEPARATOR macro definitions in misc.h. These must be defined according to the file path convention on the the target platform (e.g. '\' and '.' for DOS or Windows).

Licence and Disclaimer

These programs are free software; you can redistribute them and/or modify them 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.

These programs are distributed in the hope that they 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 these programs; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


SF3KtoObj and SF3KtoMtl were designed and programmed by Christopher Bazley.

My information on the Wavefront Object File and Material Library File formats came from Paul Bourke's copies of the file format specifications for the Advanced Visualizer software (© 1995 Alias|Wavefront, Inc.)

Some colour names were taken from a survey run by the web comic XKCD. The data is in the public domain, available under a Creative Commons licence. Thanks to Keith McKillop for suggesting this source.

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

Valid HTML 4.0!