diff --git a/Doc/ToolTables b/Doc/ToolTables
new file mode 100644
index 0000000000000000000000000000000000000000..e09cecf0a3ff6cd8e1679e11f63b9fb9156ffae2
--- /dev/null
+++ b/Doc/ToolTables
@@ -0,0 +1,88 @@
+Tool translation tables
+=======================
+Design
+------
+Tools sprite designers can optionally provide a set of precalculated translation tables to map the toolsprites onto the standard 16 Wimp colours.
+
+Historically toolsprites have relied on one of two methods to adapt the sprite designs to match the application programmer's template colour choices:
+a) Scatter some transparent pixels through the toolsprites so that the
+   underlying Wimp solid fill leaks through.
+b) From Ursula onwards, if the toolsprite is 256 colours or less and solid,
+   then the Wimp will tint grey (R=G=B) portions of the titlebar sprites
+   with the underlying Wimp solid fill colour. The 'colourmoreborder' switch
+   applied tinting to the other highlighted elements (back, close, iconise,
+   toggle, adjust, arrows) but the code is disabled on aesthetic grounds. 
+
+These schemes have some drawbacks:
+ - designers don't want to have transparency because it is binary and
+   therefore gives tools a spotty dithered look
+ - solid tools may not be tinted in the designer's desired style
+ - solid tools may by default themselves be tinted, and therefore not grey,
+   and therefore the tinting doesn't apply anyway
+ - resulting in the solid tool obliterating the template's colour choice, for
+   example writable menus are grey 2 by default, rather than the cream 12
+   that might be inferred if only considering input focus status
+
+Though alpha blending may appear to be one solution, the situation where alpha blending is also used to make the window itself translucent would result in two computationally expensive operations - blending the template colour choice with the tool sprite, then blending the result with the underlying desktop.
+
+To mitigate these drawbacks the template designer can supply precalculated custom colour translation tables alongside the toolsprites.
+
+It is generally assumed that within a tool set the variants will infact all be the same basic design and that the variations are mainly in their colouring. One way to think of this is the sprites provide a clay mould and the translation tables supply details of which paints to use - a more space efficient solution than providing 16 complete paletted sprite sets.
+
+As a guide, there are about 35000 pixels in a 90x90 set, so providing EX1 EY1
+and EX1 EY2 sets would be approximately:
+
+  Colour space                      90x45  + 90x90   Total
+  4bpp+individual palette           15.7k  + 24.9k   40.6k
+  8bpp+desktop palette              18.5k  + 37k     55.5k
+  8bpp+individual palette           118.5k + 137k    255.5k
+  16bpp                             37k    + 74k     111k
+  32bpp                             74k    + 148k    222k
+  A typical 2 table scheme (2k)     18.5k  + 37+2k   57.5k
+  A fully tabled scheme (17k)       18.5k  + 37+17k  72.5k
+
+While 32K and 16M colour tables could in future be supported, their large table size is likely to make them of limited use. Therefore this scheme will use 256 entry tables - note that that's 256 colours from a 16M colour palette for each of the toolsprite elements that can be coloured
+  1. Title bar and gadgets
+  2. Scroll bar inner
+  3. Scroll bar outer
+  4. Elements with input focus
+
+which is up to 1024 colours on screen in total (for 8bpp and lower obviously the hardware is the limiting factor). This is likely to deal even the most complex of design arrangements. 
+
+Details
+-------
+Each table is containerised as a sprite, a 16x16 in 16M colours is suggested since that can then be viewed in !Paint, but not required - any 256 word sized sprite will do.
+
+The 'extension area' of the sprite file format was considered, but this is often stripped by editors, making it difficult to visualise. Sprites can be designed using !Paint and the palettes removed at the final step (which will make them appear in "false colour" usually - remember to keep the originals!).
+
+Encoding the table in a palette of a (eg.) 1x1 sprite was also considered, but the inclusion of flashing colours in sprite palettes made this method wasteful.
+
+The table(s) are named
+  table_<wimpcolour>
+
+following the same naming scheme as the optional window background textures. A simple set might contain
+  table_2       (for sc_lightgrey)
+  table_12      (for sc_cream)
+
+A fully specified set would be 16k in total, one for each of the 16 Wimp colours.
+
+Where no tables are provided, behaviour described in (a) and (b) above will prevail, using a default translation table from ColourTrans_GenerateTable.
+
+Where a need to plot a tinted border occurs (see 'colourmoreborder') if the tint colour matches one of the standard Wimp colours that will be used, where no specific table has been supplied table_2 will be used. First, the colours will be forcefully greyscaled, then the tinting algorithm from (b) applied.
+If this jars particularly with the designers aim, a full set of tables should be provided instead so the tinting is then only needed for the rare situation of a non standard true colour being chosen (using the 'C' validation string).
+
+Where a need to plot a non tinted border occurs if the colour required matches one of the standard Wimp colours that will be used, where no specific table has been supplied table_2 will be used.
+
+Plotting
+--------
+As stated earlier, 256 translation table entries each of 32b are provided for. Plotting these into
+  1bpp  => table reduced into 256B form at 1bpp via ColourTrans
+  2bpp  => table reduced into 256B form at 2bpp via ColourTrans
+  4bpp  => table reduced into 256B form at 4bpp via ColourTrans
+  8bpp  => table reduced into 256B form at 8bpp via ColourTrans
+  16bpp => table reduced into 512B form at 16bpp via ColourTrans 
+  32bpp => uses table provided directly
+
+Calibration
+-----------
+Translation tables are not currently (re)calibrated.
diff --git a/Options/s/!Default b/Options/s/!Default
index e2ffcb3a1d1e1a13f8d65c0dd33b726e55d1b2c3..3a3aa19b33d9598f1c0527cd0851131473fe5001 100644
--- a/Options/s/!Default
+++ b/Options/s/!Default
@@ -85,6 +85,7 @@
 
         Option  RO4,                    false                   ; RISC OS 4 extensions
         Option  Sprites11,              true                    ; sprite selection scheme that allows use of Sprites11 files
+        Option  ToolTables,             true                    ; look for precalculated tool translation tables
 
         Option  RegisterMessages,       false
         Option  RegisterTools2D,        false
diff --git a/Resources/UK/Raspberry/DiscSprites/Tools,ff9 b/Resources/UK/Raspberry/DiscSprites/Tools,ff9
new file mode 100644
index 0000000000000000000000000000000000000000..b718d3f8643ba2ce1ef97cea7cfab1a31d3f2771
Binary files /dev/null and b/Resources/UK/Raspberry/DiscSprites/Tools,ff9 differ
diff --git a/Resources/UK/Raspberry/Tools,ff9 b/Resources/UK/Raspberry/Tools,ff9
index 3e5886f5b82f3fbe727e86362b954602a08857e4..4c8d863749feb4c9760dc30b368416aef02b7247 100644
Binary files a/Resources/UK/Raspberry/Tools,ff9 and b/Resources/UK/Raspberry/Tools,ff9 differ
diff --git a/TestO/TTTTest,ff9 b/TestO/TTTTest,ff9
new file mode 100644
index 0000000000000000000000000000000000000000..b72371ff0d6cf649b22aadf53b5113031ca12fa5
Binary files /dev/null and b/TestO/TTTTest,ff9 differ
diff --git a/VersionASM b/VersionASM
index 028c0854a253e34469baf5acbb064569eaab046b..4076d61afb679fe5f086e139f899d5522e60c738 100644
--- a/VersionASM
+++ b/VersionASM
@@ -1,7 +1,7 @@
 ;
 ; This file is automatically maintained by srccommit, do not edit manually.
 ; Last processed by srccommit version: 1.1.
-; 
+;
                         GBLS    Module_MajorVersion
                         GBLA    Module_Version
                         GBLS    Module_MinorVersion
@@ -11,13 +11,13 @@
                         GBLS    Module_HelpVersion
                         GBLS    Module_ComponentName
                         GBLS    Module_ComponentPath
-Module_MajorVersion     SETS    "5.29"
-Module_Version          SETA    529
+Module_MajorVersion     SETS    "5.30"
+Module_Version          SETA    530
 Module_MinorVersion     SETS    ""
-Module_Date             SETS    "21 May 2013"
-Module_ApplicationDate  SETS    "21-May-13"
+Module_Date             SETS    "01 Jun 2013"
+Module_ApplicationDate  SETS    "01-Jun-13"
 Module_ComponentName    SETS    "Wimp"
 Module_ComponentPath    SETS    "castle/RiscOS/Sources/Desktop/Wimp"
-Module_FullVersion      SETS    "5.29"
-Module_HelpVersion      SETS    "5.29 (21 May 2013)"
+Module_FullVersion      SETS    "5.30"
+Module_HelpVersion      SETS    "5.30 (01 Jun 2013)"
                         END
diff --git a/VersionNum b/VersionNum
index e9cdf70056141fb682cebef0d33b7e8f71a98d41..aacf86b9650091e45e69cbba5b3c3d74faabf4e4 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,23 +1,23 @@
-/* (5.29)
+/* (5.30)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  * Last processed by srccommit version: 1.1.
  *
- */ 
-#define Module_MajorVersion_CMHG        5.29
+ */
+#define Module_MajorVersion_CMHG        5.30
 #define Module_MinorVersion_CMHG        
-#define Module_Date_CMHG                21 May 2013
+#define Module_Date_CMHG                01 Jun 2013
 
-#define Module_MajorVersion             "5.29"
-#define Module_Version                  529
+#define Module_MajorVersion             "5.30"
+#define Module_Version                  530
 #define Module_MinorVersion             ""
-#define Module_Date                     "21 May 2013"
+#define Module_Date                     "01 Jun 2013"
 
-#define Module_ApplicationDate          "21-May-13"
+#define Module_ApplicationDate          "01-Jun-13"
 
 #define Module_ComponentName            "Wimp"
 #define Module_ComponentPath            "castle/RiscOS/Sources/Desktop/Wimp"
 
-#define Module_FullVersion              "5.29"
-#define Module_HelpVersion              "5.29 (21 May 2013)"
-#define Module_LibraryVersionInfo       "5:29"
+#define Module_FullVersion              "5.30"
+#define Module_HelpVersion              "5.30 (01 Jun 2013)"
+#define Module_LibraryVersionInfo       "5:30"
diff --git a/s/Wimp01 b/s/Wimp01
index 6c8824330f392aaab0f00935baa09d32542c0dde..c20100cb12ef7c0b6a9598a75c388e759dc2fb3d 100644
--- a/s/Wimp01
+++ b/s/Wimp01
@@ -1305,6 +1305,14 @@ tool_plotop     #       4               ; sprite op to plot sprites with
 tool_maskop     #       4
 tool_scaling    #       4               ; -> scaling block (may not be used)
 tool_transtable #       4               ; -> translation table (may not be used)
+ [ ToolTables
+ttt_masterset   #       16*4            ; -> user supplied tool translation tables (one per wimp colour)
+ttt_activeset   #       16*4            ; -> reprocessed for this mode
+ttt_activeset_at #      4
+ttt_activeset_size #    4
+ttt_lastlookup  #       4               ; most recent colour match
+ttt_table2      *       2*4
+ ]
 tool_scrollclip #       4*4             ; clip region used for plotting scroll bars
 tool_scalingblk #       4*4             ; scaling block used for painting glyphs
 
@@ -3666,7 +3674,10 @@ gotwork
 
         STR     R0,tpixtable_at         ; no tool pixel translation table
         STR     R0,tpixtable_size
-
+        [ ToolTables
+        STR     R0,ttt_activeset_at     ; no custom translation tables
+        STR     R0,ttt_activeset_size
+        ]
         STR     R0,list_at
         STR     R0,list_size            ; mark to indicate now list present
         STR     R0,filehandle
diff --git a/s/Wimp04 b/s/Wimp04
index 1784d440576d1dcfe0d6d56b9ca5413e5aaf88d8..6c51fe0f98943db121dd82b6bef92b40a0db91cb 100644
--- a/s/Wimp04
+++ b/s/Wimp04
@@ -958,20 +958,12 @@ mungetruecolours ROUT
 
         LTORG
 
-fadetruecolour ROUT
-        ; In:  R0 -> palette entry to fade
-        ;      R2 =  window background palette entry, or -1 to turn off special case
-        ; Out: [R0] updated: grey, and half the distance from white (cf sprites, which are 1/4 the distance from white)
-        Push    "R1, R2, R4, R14"
-        LDR     R4, [R0]
-
-        TEQ     R4, R2
-        Pull    "R1, R2, R4, PC", EQ    ; leave icon background alone if it matches the work area background
-
+bgr0_to_y ROUT
+        Push    "R1-R3,LR"
         MOV     R14, #&FF
-        AND     R1, R14, R4, LSR #8     ; extract red
-        AND     R2, R14, R4, LSR #16    ; extract green
-        AND     R3, R14, R4, LSR #24    ; extract blue
+        AND     R1, R14, R0, LSR #8     ; extract red
+        AND     R2, R14, R0, LSR #16    ; extract green
+        AND     R3, R14, R0, LSR #24    ; extract blue
 
         MOV     R14,#77
         MUL     R14,R1,R14              ; red *77
@@ -983,19 +975,33 @@ fadetruecolour ROUT
         ADD     R14,R14,#&7F            ; Rounding
         ADD     R14,R14,R14,LSL #8      ; Make 16 bit fractional
         ADD     R14,R14,#&100           ; Rounding
-        MOV     R14,R14,LSR #16         ; Convert to 8bit luma
+        MOV     R0,R14,LSR #16          ; Convert to 8 bit luma
+        Pull    "R1-R3,PC"
+
+fadetruecolour ROUT
+        ; In:  R0 -> palette entry to fade
+        ;      R2 =  window background palette entry, or -1 to turn off special case
+        ; Out: [R0] updated: grey, and half the distance from white (cf sprites, which are 1/4 the distance from white)
+        Push    "R0, R4, R14"
+        MOV     R4, R0
+        LDR     R0, [R4]
+
+        TEQ     R14, R2
+        Pull    "R0, R4, PC", EQ        ; leave icon background alone if it matches the work area background
+
+        BL      bgr0_to_y
 
-        RSBS    R14, R14, #&FF          ; get distance from white
+        RSBS    R14, R0, #&FF           ; get distance from white
         MOVMI   R14, #0                 ; just in case
         MOV     R14, R14, LSR #1        ; divide by 2
         RSB     R14, R14, #&FF          ; invert back
 
-        MOV     R4, R14, LSL #8
-        ORR     R4, R4, R14, LSL #16
-        ORR     R4, R4, R14, LSL #24    ; recombine to make &BBGGRR00
+        MOV     R0, R14, LSL #8
+        ORR     R0, R0, R14, LSL #16
+        ORR     R0, R0, R14, LSL #24    ; recombine to make &BBGGRR00
 
-        STR     R4, [R0]
-        Pull    "R1, R2, R4, PC"
+        STR     R0, [R4]
+        Pull    "R0, R4, PC"
       ]
 
 
diff --git a/s/Wimp10 b/s/Wimp10
index 6afb49ceebce56b809fc4476b136d4c99822b530..cc450003717d18fc3c5b850867d820b96b7d4ad7 100644
--- a/s/Wimp10
+++ b/s/Wimp10
@@ -421,8 +421,15 @@ ct_grey         = sc_verylightgrey, sc_verylightgrey, sc_verylightgrey, sc_veryl
 ;; All gadgets must be defined with the same palette and same mode, mixing is not
 ;; allowed.  Sprites are allowed to have mode suffix to allow different
 ;; EX EY factors to be supported.
+;;
+;; Tools sprite designers can optionally provide a set of precalculated translation
+;; tables to map the toolsprites onto the standard 16 Wimp colours. Each table is
+;; containerised as a sprite, but really it's just a translation table in disguise.
 ;;-----------------------------------------------------------------------------
 
+tablebasename
+        DCB     "table_1?", 0           ; Like background tiles, table_<wimpcolour>
+        ALIGN
 
 ;;-----------------------------------------------------------------------------
 ;; Define the list of sprites and its workspace for the caching block.
@@ -529,6 +536,51 @@ maketoollist EntryS "R1-R11"
         TEQ     R2,#0
         BEQ     %FT45                   ; No then jump
 
+      [ ToolTables
+
+; look for any custom translation tables
+
+        SUB     R13,R13,#12             ; space for "table_99"+0
+        MOV     R4,#0                   ; bitmap of found wimp colours
+        MOV     R5,#15                  ; wimp colour loop counter
+        ADRL    R6,ttt_masterset
+02
+        ADR     R0,tablebasename
+        MOV     R1,R13
+        BL      copy0
+        CMP     R5,#10                  ; numbery bit
+        ADDCS   R0,R5,#'0' - 10
+        STRCSB  R0,[R1,#-1]!
+        ADDCC   R0,R5,#'0'
+        STRCCB  R0,[R1,#-2]!
+        MOV     R0,#0
+        STRB    R0,[R1,#1]              ; terminate
+
+        LDR     R0,=&100+SpriteReason_SelectSprite
+        ADRL    R1,tool_areaCB
+        MOV     R2,R13
+        SWI     XOS_SpriteOp
+        MOVVC   R0,#1                   ; hit
+        ORRVC   R4,R4,R0,LSL R5
+        LDRVC   R1,[R2,#spImage]
+        ADDVC   R2,R2,R1
+        MOVVS   R2,#0                   ; miss
+        STR     R2,[R6,R5,LSL #2]       ; start of containerised 256x4 translation table
+
+        SUBS    R5,R5,#1
+        BPL     %BT02
+
+; consider the results
+
+        ADD     R13,R13,#12
+        MOVS    R0,R4,LSL #16
+        BEQ     %FT05                   ; we aint got naffin
+
+        TST     R4,#1:SHL:2
+        BLEQ    freetoolarea
+        BEQ     %FT45                   ; need 'table_2' for tinting, can't use these tools
+05
+      ]
 ;..............................................................................
 ;
 ; attempt to work out the sizes of the various sprites and their modifications to
@@ -999,6 +1051,204 @@ default_params
 
         MOV     PC,LR
 
+  [ ToolTables
+;;-----------------------------------------------------------------------------
+;; make an active set of translation tables from the master set for this mode
+;;
+;; in    [ttt_masterset] have master tables, at least 'table_2' must exist
+;; out   [ttt_activeset] updated
+;;       V set R0 -> error, else corrupt
+;;------------------------------------------------------------------------------
+
+mastertoactive ROUT
+        Push    "R1-R8,LR"
+        ADRL    R6,ttt_masterset
+        MOV     R1,#0
+        MOV     R0,#15
+05
+        LDR     R14,[R6,R0,LSL #2]
+        TEQ     R14,#0
+        ADDNE   R1,R1,#1
+        SUBS    R0,R0,#1
+        BPL     %BT05
+
+        LDR     R5,log2bpp              ; bpp 0,1,2,3,4,5
+        CMP     R5,#4
+        MOVCC   R7,#256
+        MOVEQ   R7,#512
+        MOVHI   R7,#1024                ; => bytes per table entry
+        MUL     R3,R1,R7                ; => bytes for all the tables present
+
+        LDR     R2,ttt_activeset_at
+        TEQ     R2,#0
+        BEQ     %FT15                   ; none claimed yet
+
+        CMP     R5,#5
+        LDRNE   R14,ttt_activeset_size
+        MOVEQ   R14,#0                  ; 32bpp, no copies needed, force a free
+        CMP     R14,R3
+        BCS     %FT20                   ; big enough
+10
+        MOV     R14,#0
+        STR     R14,ttt_activeset_at
+        MOV     R0,#ModHandReason_Free
+        BL      XROS_Module             ; too small, free old one
+15
+        CMP     R5,#5
+        BEQ     %FT20                   ; 32bpp, no copies needed, skip the claim
+        MOV     R0,#ModHandReason_Claim
+        STR     R3,ttt_activeset_size
+        BL      XROS_Module
+        Pull    "R1-R8,PC",VS
+        STR     R2,ttt_activeset_at
+20
+        ADRL    R4,ttt_activeset
+        MOV     R3,#15                  ; for each master table present, generate user table
+25
+        ; R1=colour number to convert (0-255)
+        ; R2->base of storage for user tables
+        ; R3=wimp colour (0-15)
+        ; R4->table of user pointers
+        ; R5=log2bpp
+        ; R6->table of master pointers
+        ; R7=size of 1 user table in bytes
+        ; R8->base of master table for this wimp colour
+        LDR     R8,[R6,R3,LSL #2]
+        CMP     R8,#0                   ; master table absent?
+        CMPNE   R5,#5                   ; or 32bpp mode?
+        STREQ   R8,[R4,R3,LSL #2]
+        BEQ     %FT35
+
+        MOV     R1, #255
+30
+        LDR     R0,[R8,R1,LSL #2]
+        MOV     R0,R0,ROR #24           ; xBGR->BGRx
+        SWI     XColourTrans_ReturnColourNumber
+        CMP     R5,#4                   ; 16bpp is 2B/entry, others are 1
+        STRCCB  R0,[R2,R1]
+        ADDEQ   R14,R2,R1,LSL #1
+        STREQB  R0,[R14,#0]
+        MOVEQ   R0,R0,LSR #8
+        STREQB  R0,[R14,#1]
+        SUBS    R1,R1,#1
+        BPL     %BT30
+
+        STR     R2,[R4,R3,LSL #2]       ; point at the table just made
+        ADD     R2,R2,R7                ; move storage along
+35
+        SUBS    R3,R3,#1                ; next wimp colour
+        BPL     %BT25
+
+        CLRV
+        Pull    "R1-R8,PC"
+
+;;-----------------------------------------------------------------------------
+;; colour match the tool to a standard colour
+;;
+;; in    R1 = &BBGGRR00 true colour (or 4 bit wimp colour when not TrueIcon3)
+;; out   R7 -> translation table to use
+;;------------------------------------------------------------------------------
+
+colourmatchtool
+        Push    "R2-R3,LR"
+        ADRL    R3,ttt_activeset
+        LDR     R7,[R3,#ttt_table2]     ; Presence of 'table_2' implies custom translations
+        TEQ     R7,#0
+        LDREQ   R7,tool_transtable      ; Use generic translation table
+        Pull    "R2-R3,PC",EQ
+
+        STR     R1,ttt_lastlookup       ; remember last request incase ColourTrans invalidates everything
+    [ TrueIcon3
+        BL      getpalpointer           ; R14 -> active 16 entry palette
+        MOV     R2,#15
+10
+        LDR     R7,[R14,R2,LSL #2]
+        TEQ     R1,R7
+        BNE     %FT15
+        LDR     R7,[R3,R2,LSL #2]
+        TEQ     R7,#0
+        Pull    "R2-R3,PC",NE           ; Is a standard colour & have a custom translation
+15
+        SUBS    R2,R2,#1
+        BPL     %BT10
+
+        LDRB    R2,tinted_tool          ; Non standard, or no table, maybe tint it?
+        TEQ     R2,#0
+        LDREQ   R7,[R3,#ttt_table2]     ; Not a tinting candidate, use 'table_2'
+        Pull    "R2-R3,PC",EQ
+
+        Push    "R0-R1"                 ; Make a temporary tinting table
+
+      [ Medusa
+        LDR     R1,log2bpp              ; bpp 0,1,2,3,4,5
+        CMP     R1,#4
+        MOVCC   R1,#256
+        MOVEQ   R1,#512
+        MOVHI   R1,#1024                ; => bytes per table entry
+      |
+        MOV     R1,#256
+      ]
+        LDR     R2,tpixtable_at
+        LDR     R3,tpixtable_size
+        TEQ     R2,#0
+        BEQ     %FT20
+        CMP     R3,R1                   ; Is what's there already big enough?
+        BCS     %FT25
+        MOV     R0,#0
+        STR     R0,tpixtable_at
+        MOV     R0,#ModHandReason_Free
+        BL      XROS_Module
+20
+        MOV     R3,R1
+        MOV     R0,#ModHandReason_Claim
+        BL      XROS_Module
+        MOVVS   R7,#0                   ; Out of memory, and no tpixtable! Use nothing
+        Pull    "R0-R3,PC",VS
+25
+        STR     R2,tpixtable_at
+        STR     R2,tool_transtable
+        STR     R3,tpixtable_size
+
+        ADRL    R3,ttt_masterset
+        LDR     R7,[R3,#ttt_table2]     ; Use master 'table_2' as basis
+
+        MOV     R1,#255
+        LDR     R3,log2bpp
+        ; R1=colour number to convert (0-255)
+        ; R2->base of tinted translation table
+        ; R3=log2bpp
+        ; R7->base of master table 2
+30
+        LDR     R0,[R7,R1,LSL #2]       ; solid (0) -> transparent (255)
+        MOV     R0,R0,ROR #24           ; &AABBGGRR -> &BBGGRRAA
+        BL      bgr0_to_y
+        ORR     R0,R0,R0,LSL #8         ; &0000YYYY
+        ORR     R0,R0,R0,LSL #16        ; &YYYYYYYY
+        BL      tintfunc
+        SWI     XColourTrans_ReturnColourNumber
+      [ Medusa
+        CMP     R3,#4                   ; 32bpp is 4B/entry, 16bpp is 2B/entry, others are 1
+        STRCCB  R0,[R2,R1]
+        ADDEQ   R14,R2,R1,LSL #1
+        STREQB  R0,[R14,#0]
+        MOVEQ   R0,R0,LSR #8
+        STREQB  R0,[R14,#1]
+        STRHI   R0,[R2,R1,LSL #2]
+      |
+        STRB    R0,[R1,R1]              ; No wide translation tables
+      ]
+        SUBS    R1,R1,#1
+        BPL     %BT30
+
+        MOV     R7,R2                   ; Use table just made
+        Pull    "R0-R3,PC"
+    |
+        LDR     R7,[R3,R1,LSL #2]       ; Direct lookup wimp colour
+        TEQ     R7,#0
+        LDREQ   R7,[R3,#ttt_table2]     ; No specific table, use 'table_2'
+        Pull    "R2-R3,PC"
+    ]
+  ]
 
 ;;-----------------------------------------------------------------------------
 ;; free the tool sprites list (if defined)
@@ -1043,6 +1293,13 @@ freetooltrans ROUT
         MOV     R0,#0
         STR     R0,tpixtable_at
         STR     R0,tool_transtable
+      [ ToolTables
+        LDR     R2,ttt_activeset_at
+        STR     R0,ttt_activeset_at
+        CMP     R2,#0                   ; have translation tables been supplied in the tool sprites?
+        MOVNE   R0,#ModHandReason_Free
+        BLNE   XROS_Module
+      ]
 ;
         CLRV
         MOV     PC,R1
@@ -1121,7 +1378,7 @@ ToolSprites_Code Entry "R0"
 int_toolsprites Entry "R1-R6"
 
         MOVS    R1,R0                   ; if null then use default tools
-        ADREQL  R1,default_tools
+        ADREQ   R1,default_tools
 ;
         DebugS  tools,"ToolSprites =",R1
 ;
@@ -1606,6 +1863,14 @@ plot_windowglyph Entry "R0-R9"
 ;
         ADRL    R0,tool_plotparams
         LDMIA   R0,{R0,R5,R6,R7}        ; parameters to plot using
+    [ ToolTables
+      [ TrueIcon3
+        LDR     R1,truetitlecolour
+      |
+        LDRB    R1,titlecolour
+      ]
+        BL      colourmatchtool
+    ]
         Debug   tools2,"SpriteOp =",R0,R1,R2,R3,R4,R5
         BL      Tool_SpriteOp
 
@@ -1832,6 +2097,14 @@ draw_spriteglyph EntryS "R0-R7"
 ;
         ADRL    R0,tool_plotparams
         LDMIA   R0,{R0,R5,R6,R7}        ; get the tool information
+    [ ToolTables
+      [ TrueIcon3
+        LDR     R1,truetitlecolour
+      |
+        LDRB    R1,titlecolour
+      ]
+        BL      colourmatchtool
+    ]
         BL      Tool_SpriteOp
 ;
         EXITS
@@ -1919,6 +2192,14 @@ dofunkytitlebar EntryS "R0-R11"
 ;
         ADRL    R0,tool_plotparams
         LDMIA   R0,{R0,R5,R6,R7}        ; R0,R5-R7 => sprite op information
+    [ ToolTables
+      [ TrueIcon3
+        LDR     R1,truetitlecolour
+      |
+        LDRB    R1,titlecolour
+      ]
+        BL      colourmatchtool
+    ]
         LDR     R1,tool_list            ; -> list of the glyphs
         Push    "R10,R11"               ; preserve these - they are important
 ;
@@ -2074,6 +2355,14 @@ dofunkyvscroll EntryS "R0-R11"
 ;
         ADRL    R0,tool_plotparams
         LDMIA   R0,{R0,R5,R6,R7}        ; get the plotting parameters
+    [ ToolTables
+      [ TrueIcon3
+        LDR     R1,truescoutcolour
+      |
+        LDRB    R1,[handle,#w_scouter]
+      ]
+        BL      colourmatchtool
+    ]
 ;
         LDR     R1,dy                   ; single pixel at screen resolution
         LDR     R3,[sp,#Proc_RegOffset+sp_x0]
@@ -2135,6 +2424,16 @@ dofunkyvscroll EntryS "R0-R11"
 ; now decide which routine to call to plot the sausage bits
 ;
         LDR     R2,[sp,#Proc_RegOffset+sp_hand]
+    [ ToolTables
+        Push    "R1"
+      [ TrueIcon3
+        LDR     R1,truescincolour
+      |
+        LDRB    R1,[R2,#w_scinner]
+      ]
+        BL      colourmatchtool
+        Pull    "R1"
+    ]
       [ PushBothBars
         LDR     R14, border_iconselected
         CMP     R14, #windowicon_verticalbar
@@ -2274,6 +2573,15 @@ dofunkyhscroll EntryS "R0-R11"
 ;
         ADRL    R0,tool_plotparams
         LDMIA   R0,{R0,R5,R6,R7}        ; get the plotting parameters
+    [ ToolTables
+      [ TrueIcon3
+        LDR     R1,truescoutcolour
+      |
+        LDRB    R1,[handle,#w_scouter]
+      ]
+        BL      colourmatchtool
+    ]
+;
         LDR     R1,dx                   ; single pixel at screen resolution
         LDR     R4,[sp,#Proc_RegOffset+sp_y0]
         LDR     R10,tool_list           ; -> tool sprite list
@@ -2333,6 +2641,16 @@ dofunkyhscroll EntryS "R0-R11"
 ; first attempt to decide if the block is selected or not?
 ;
         LDR     R2,[sp,#Proc_RegOffset+sp_hand]
+    [ ToolTables
+        Push    "R1"
+      [ TrueIcon3
+        LDR     R1,truescincolour
+      |
+        LDRB    R1,[R2,#w_scinner]
+      ]
+        BL      colourmatchtool
+        Pull    "R1"
+    ]
       [ PushBothBars
         LDR     R14, border_iconselected
         CMP     R14, #windowicon_horizbar
@@ -2884,8 +3202,8 @@ cachetoolspritedata
         CMP     R7,R14                  ; min(image,trans)
         MOVHI   R7,R14
 
-        LDR     R14,tpixtable_at
-        CMP     R14,#0                  ; is a pixtable defined?
+        LDR     R1,tpixtable_at
+        CMP     R1,#0                   ; is a pixtable defined?
         BEQ     %FT10
 
       [ TrueIcon3
@@ -2893,10 +3211,17 @@ cachetoolspritedata
         TEQ     R14, #0                 ; if it's tinted, we must recalculate the table
         BNE     %FT10
       ]
+      [ ToolTables
+        ADRL    R14,ttt_masterset
+        LDR     R14,[R14,#ttt_table2]   ; if it's a custom set, we must recalculate the table
+        TEQ     R14,#0
+        BNE     %FT10
+      ]
 
         TEQ     R7,#spPalette           ; does it have a palette?
         LDREQ   R14,tsprite_lastmode
         TEQEQ   R6,R14                  ; no, so have we already cached this information?
+        STREQ   R1,tool_transtable      ; repoint at the pixtable
         BEQ     %FT92
 
 10      MOV     R0,R6                   ; R0 = mode of sprite
@@ -2923,6 +3248,9 @@ cachetoolspritedata
         MOVVC   R1,#VduExt_YEigFactor
         SWIVC   XOS_ReadModeVariable
         STRVC   R2,tsprite_log2py       ; get the Y scaling factor (pixels => OS units)
+      [ ToolTables
+        BLVC    mastertoactive          ; remap any custom translation tables
+      ]
         Pull    "R2,R3-R4",VS
         BVS     %FT92
 
@@ -3000,8 +3328,20 @@ cachetoolspritedata
         BPL     %BT05                   ; loop back copying the data
 
         Pull    "R0-R3,R5"
+10
+      [ ToolTables
+        ADRL    R14,ttt_masterset
+        LDR     R14,[R14,#ttt_table2]   ; are these sprites using custom translations?
+        TEQ     R14,#0
+        BEQ     %FT15
 
-10      MOV     R4,#0                   ; R4 =0 read table size
+        LDR     R1,ttt_lastlookup
+        BL      colourmatchtool         ; redo the last lookup
+        MOV     R14,R7
+        B       %FT45                   ; skip the generic table generation
+15
+      ]
+        MOV     R4,#0                   ; R4 =0 read table size
       [ TrueIcon3
         SWI     XColourTrans_GenerateTable ; ensure wide table flag is obeyed
       |
@@ -3064,6 +3404,9 @@ cachetoolspritedata
         TEQ     R14,R6                  ; colour number = index? (1:1 mapped)
         BEQ     %BT35
 40
+        LDR     R14,tpixtable_at        ; use that now
+45
+        STR     R14,tool_transtable
         MOV     R14,#-1
         STRB    R14,tsprite_needsfactors; mark as needing translation
 90
@@ -3203,9 +3546,6 @@ recache_tools_trans
 
         BL      cachetoolspritedata     ; this sets up the tool pixtable area
 
-        LDRVC   R0,tpixtable_at
-        STRVC   R0,tool_transtable      ; update the new table location
-
         CLRV                            ; clear errors
         Pull    "R0-R4,PC"
  ]