summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/icons
diff options
context:
space:
mode:
authorFranklin Wei <frankhwei536@gmail.com>2016-11-20 15:16:41 -0500
committerFranklin Wei <frankhwei536@gmail.com>2016-11-24 16:23:09 -0500
commit56c9984511f016eab7e1278ba9e40d88bb59a162 (patch)
tree1bfa6d3aeb3bf2a6ffec71387ac073cd0b8b2a51 /apps/plugins/puzzles/icons
parent29648f817677b84c03c2bcfe89eb8cf53653e7db (diff)
downloadrockbox-puzzles.zip
rockbox-puzzles.tar.gz
rockbox-puzzles.tar.bz2
rockbox-puzzles.tar.xz
[WIP] Port of Simon Tatham's Puzzle Collectionpuzzles
Original revision: 5123b1bf68777ffa86e651f178046b26a87cf2d9 MIT Licensed. Some games still crash and others are unplayable due to issues with controls. Still need a "real" polygon filling algorithm. The following games are at least partially broken for various reasons: Cube: crash with certain settings Galaxies: crash Inertia: crash Keen: input issues Loopy: weird stuff happens Map: crash on input Mines: weird stuff happens on target Palisade: input issues Signpost: crash on input Solo: input issues Towers: input and drawing issues Train Tracks: drawing issues Twiddle: weird animation on target Undead: input and drawing issues Unequal: input and drawing issues Untangle: input issues All in all, about 40% of the games are at least partially broken. Change-Id: I7c69b6860ab115f973c8d76799502e9bb3d52368
Diffstat (limited to 'apps/plugins/puzzles/icons')
-rw-r--r--apps/plugins/puzzles/icons/Makefile153
-rw-r--r--apps/plugins/puzzles/icons/blackbox.sav27
-rw-r--r--apps/plugins/puzzles/icons/bridges.sav72
-rwxr-xr-xapps/plugins/puzzles/icons/cicon.pl27
-rwxr-xr-xapps/plugins/puzzles/icons/crop.sh37
-rw-r--r--apps/plugins/puzzles/icons/cube.sav22
-rw-r--r--apps/plugins/puzzles/icons/dominosa.sav53
-rw-r--r--apps/plugins/puzzles/icons/fifteen.sav74
-rw-r--r--apps/plugins/puzzles/icons/filling.sav38
-rw-r--r--apps/plugins/puzzles/icons/flip.sav20
-rw-r--r--apps/plugins/puzzles/icons/flood.sav14
-rw-r--r--apps/plugins/puzzles/icons/galaxies.sav51
-rw-r--r--apps/plugins/puzzles/icons/guess.sav15
-rwxr-xr-xapps/plugins/puzzles/icons/icon.pl270
-rw-r--r--apps/plugins/puzzles/icons/inertia.sav30
-rw-r--r--apps/plugins/puzzles/icons/keen.sav62
-rw-r--r--apps/plugins/puzzles/icons/lightup.sav24
-rw-r--r--apps/plugins/puzzles/icons/loopy.sav120
-rw-r--r--apps/plugins/puzzles/icons/magnets.sav33
-rw-r--r--apps/plugins/puzzles/icons/map.sav27
-rw-r--r--apps/plugins/puzzles/icons/mines.sav67
-rw-r--r--apps/plugins/puzzles/icons/net.sav53
-rw-r--r--apps/plugins/puzzles/icons/netslide.sav47
-rw-r--r--apps/plugins/puzzles/icons/palisade.sav50
-rw-r--r--apps/plugins/puzzles/icons/pattern.sav29
-rw-r--r--apps/plugins/puzzles/icons/pearl.sav23
-rw-r--r--apps/plugins/puzzles/icons/pegs.sav16
-rw-r--r--apps/plugins/puzzles/icons/range.sav36
-rw-r--r--apps/plugins/puzzles/icons/rect.sav17
-rw-r--r--apps/plugins/puzzles/icons/samegame.sav34
-rwxr-xr-xapps/plugins/puzzles/icons/screenshot.sh25
-rw-r--r--apps/plugins/puzzles/icons/signpost.sav23
-rw-r--r--apps/plugins/puzzles/icons/singles.sav45
-rw-r--r--apps/plugins/puzzles/icons/sixteen.sav39
-rw-r--r--apps/plugins/puzzles/icons/slant.sav51
-rw-r--r--apps/plugins/puzzles/icons/solo.sav36
-rwxr-xr-xapps/plugins/puzzles/icons/square.pl95
-rw-r--r--apps/plugins/puzzles/icons/tents.sav32
-rw-r--r--apps/plugins/puzzles/icons/towers.sav26
-rw-r--r--apps/plugins/puzzles/icons/tracks.sav31
-rw-r--r--apps/plugins/puzzles/icons/twiddle.sav35
-rw-r--r--apps/plugins/puzzles/icons/undead.sav14
-rw-r--r--apps/plugins/puzzles/icons/unequal.sav25
-rw-r--r--apps/plugins/puzzles/icons/unruly.sav22
-rw-r--r--apps/plugins/puzzles/icons/untangle.sav16
-rw-r--r--apps/plugins/puzzles/icons/win16pal.xpm23
46 files changed, 2079 insertions, 0 deletions
diff --git a/apps/plugins/puzzles/icons/Makefile b/apps/plugins/puzzles/icons/Makefile
new file mode 100644
index 0000000..00dae1f
--- /dev/null
+++ b/apps/plugins/puzzles/icons/Makefile
@@ -0,0 +1,153 @@
+# Makefile for Puzzles icons.
+
+PUZZLES = blackbox bridges cube dominosa fifteen filling flip flood \
+ galaxies guess inertia keen lightup loopy magnets map mines \
+ net netslide palisade pattern pearl pegs range rect \
+ samegame signpost singles sixteen slant solo tents towers \
+ twiddle tracks undead unequal unruly untangle
+
+BASE = $(patsubst %,%-base.png,$(PUZZLES))
+WEB = $(patsubst %,%-web.png,$(PUZZLES))
+
+IBASE = $(patsubst %,%-ibase.png,$(PUZZLES))
+IBASE4 = $(patsubst %,%-ibase4.png,$(PUZZLES))
+P48D24 = $(patsubst %,%-48d24.png,$(PUZZLES))
+P48D8 = $(patsubst %,%-48d8.png,$(PUZZLES))
+P48D4 = $(patsubst %,%-48d4.png,$(PUZZLES))
+P32D24 = $(patsubst %,%-32d24.png,$(PUZZLES))
+P32D8 = $(patsubst %,%-32d8.png,$(PUZZLES))
+P32D4 = $(patsubst %,%-32d4.png,$(PUZZLES))
+P16D24 = $(patsubst %,%-16d24.png,$(PUZZLES))
+P16D8 = $(patsubst %,%-16d8.png,$(PUZZLES))
+P16D4 = $(patsubst %,%-16d4.png,$(PUZZLES))
+ICONS = $(patsubst %,%.ico,$(PUZZLES))
+CICONS = $(patsubst %,%-icon.c,$(PUZZLES))
+RC = $(patsubst %,%.rc,$(PUZZLES))
+
+BIN = ../
+PIC = ./
+
+# Work around newer ImageMagick unilaterally distorting colours when
+# converting to PNG.
+CSP = -set colorspace RGB
+
+base: $(BASE)
+web: $(WEB)
+pngicons: $(P48D24) $(P32D24) $(P16D24)
+winicons: $(ICONS) $(RC)
+gtkicons: $(CICONS)
+all: base web pngicons winicons gtkicons
+
+# Build the base puzzle screenshots from which all the other images
+# are derived. Some of them involve showing a move animation
+# part-way through.
+fifteen-base.png : override REDO=0.3
+flip-base.png : override REDO=0.3
+netslide-base.png : override REDO=0.3
+sixteen-base.png : override REDO=0.3
+twiddle-base.png : override REDO=0.3
+$(BASE): %-base.png: $(BIN)% $(PIC)%.sav
+ $(PIC)screenshot.sh $(BIN)$* $(PIC)$*.sav $@ $(REDO)
+
+# Build the screenshots for the web, by scaling the original base
+# images to a uniform size.
+$(WEB): %-web.png: %-base.png
+ $(PIC)square.pl 150 5 $^ $@
+
+# Build the base _icon_ images, by careful cropping of the base
+# images: icons are very small so it's often necessary to zoom in
+# on a smaller portion of the screenshot.
+blackbox-ibase.png : override CROP=352x352 144x144+0+208
+bridges-ibase.png : override CROP=264x264 107x107+157+157
+dominosa-ibase.png : override CROP=304x272 152x152+152+0
+fifteen-ibase.png : override CROP=240x240 120x120+0+120
+filling-ibase.png : override CROP=256x256 133x133+14+78
+flip-ibase.png : override CROP=288x288 145x145+120+72
+galaxies-ibase.png : override CROP=288x288 165x165+0+0
+guess-ibase.png : override CROP=263x420 178x178+75+17
+inertia-ibase.png : override CROP=321x321 128x128+193+0
+keen-ibase.png : override CROP=288x288 96x96+24+120
+lightup-ibase.png : override CROP=256x256 112x112+144+0
+loopy-ibase.png : override CROP=257x257 113x113+0+0
+magnets-ibase.png : override CROP=264x232 96x96+36+100
+mines-ibase.png : override CROP=240x240 110x110+130+130
+net-ibase.png : override CROP=193x193 113x113+0+80
+netslide-ibase.png : override CROP=289x289 144x144+0+0
+palisade-ibase.png : override CROP=288x288 192x192+0+0
+pattern-ibase.png : override CROP=384x384 223x223+0+0
+pearl-ibase.png : override CROP=216x216 94x94+108+15
+pegs-ibase.png : override CROP=263x263 147x147+116+0
+range-ibase.png : override CROP=256x256 98x98+111+15
+rect-ibase.png : override CROP=205x205 115x115+90+0
+signpost-ibase.png : override CROP=240x240 98x98+23+23
+singles-ibase.png : override CROP=224x224 98x98+15+15
+sixteen-ibase.png : override CROP=288x288 144x144+144+144
+slant-ibase.png : override CROP=321x321 160x160+160+160
+solo-ibase.png : override CROP=481x481 145x145+24+24
+tents-ibase.png : override CROP=320x320 165x165+142+0
+towers-ibase.png : override CROP=300x300 102x102+151+6
+tracks-ibase.png : override CROP=246x246 118x118+6+6
+twiddle-ibase.png : override CROP=192x192 102x102+69+21
+undead-ibase.png : override CROP=416x480 192x192+16+80
+unequal-ibase.png : override CROP=208x208 104x104+104+104
+untangle-ibase.png : override CROP=320x320 164x164+3+116
+$(IBASE): %-ibase.png: %-base.png
+ $(PIC)crop.sh $^ $@ $(CROP)
+
+# Convert the full-size icon images to 4-bit colour, because that
+# seems to work better than reducing it in 24 bits and then
+# dithering.
+$(IBASE4): %-ibase4.png: %-ibase.png
+ convert -colors 16 +dither $(CSP) -map $(PIC)win16pal.xpm $^ $@
+
+# Build the 24-bit PNGs for the icons, at three sizes.
+$(P48D24): %-48d24.png: %-ibase.png
+ $(PIC)square.pl 48 4 $^ $@
+$(P32D24): %-32d24.png: %-ibase.png
+ $(PIC)square.pl 32 2 $^ $@
+$(P16D24): %-16d24.png: %-ibase.png
+ $(PIC)square.pl 16 1 $^ $@
+
+# The 8-bit icon PNGs are just custom-paletted quantisations of the
+# 24-bit ones.
+$(P48D8) $(P32D8) $(P16D8): %d8.png: %d24.png
+ convert -colors 256 $^ $@
+
+# But the depth-4 images work better if we re-shrink from the
+# ibase4 versions of the images, and then normalise the colours
+# again afterwards. (They're still not very good, but my hope is
+# that on most modern Windows machines this won't matter too
+# much...)
+$(P48D4): %-48d4.png: %-ibase4.png
+ $(PIC)square.pl 48 1 $^ $@-tmp2.png
+ convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
+ rm -f $@-tmp2.png
+$(P32D4): %-32d4.png: %-ibase.png
+ $(PIC)square.pl 32 1 $^ $@-tmp2.png
+ convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
+ rm -f $@-tmp2.png
+$(P16D4): %-16d4.png: %-ibase.png
+ $(PIC)square.pl 16 1 $^ $@-tmp2.png
+ convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
+ rm -f $@-tmp2.png
+
+# Build the actual Windows icons themselves, by feeding all those
+# PNGs to my icon builder script.
+$(ICONS): %.ico: %-48d24.png %-48d8.png %-48d4.png \
+ %-32d24.png %-32d8.png %-32d4.png \
+ %-16d24.png %-16d8.png %-16d4.png
+ $(PIC)icon.pl -24 $*-48d24.png $*-32d24.png $*-16d24.png \
+ -8 $*-48d8.png $*-32d8.png $*-16d8.png \
+ -4 $*-48d4.png $*-32d4.png $*-16d4.png > $@
+
+# Build the .RC files which bind the icons into the applications.
+$(RC): %.rc:
+ echo '#include "puzzles.rc2"' > $@
+ echo '200 ICON "$*.ico"' >> $@
+
+# Build the GTK icon source files.
+$(CICONS): %-icon.c: %-16d24.png %-32d24.png %-48d24.png
+ $(PIC)cicon.pl $^ > $@
+
+clean:
+ rm -f *.png *.ico *.rc *-icon.c
diff --git a/apps/plugins/puzzles/icons/blackbox.sav b/apps/plugins/puzzles/icons/blackbox.sav
new file mode 100644
index 0000000..4483f3c
--- /dev/null
+++ b/apps/plugins/puzzles/icons/blackbox.sav
@@ -0,0 +1,27 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :9:Black Box
+PARAMS :8:w8h8m5M5
+CPARAMS :8:w8h8m5M5
+SEED :15:999785320716678
+DESC :24:c8b9f8528193756b9a2fd24d
+UI :2:E0
+NSTATES :2:18
+STATEPOS:2:13
+MOVE :2:F2
+MOVE :2:F4
+MOVE :2:F5
+MOVE :3:F25
+MOVE :3:F26
+MOVE :3:F11
+MOVE :3:F12
+MOVE :3:F15
+MOVE :4:T7,7
+MOVE :4:T7,4
+MOVE :4:T1,7
+MOVE :2:F3
+MOVE :2:F9
+MOVE :3:F27
+MOVE :4:T5,7
+MOVE :4:T1,8
+MOVE :1:R
diff --git a/apps/plugins/puzzles/icons/bridges.sav b/apps/plugins/puzzles/icons/bridges.sav
new file mode 100644
index 0000000..ddae708
--- /dev/null
+++ b/apps/plugins/puzzles/icons/bridges.sav
@@ -0,0 +1,72 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Bridges
+PARAMS :15:10x10i30e10m2d2
+CPARAMS :15:10x10i30e10m2d2
+SEED :15:944199396008454
+DESC :49:a1a4a4b4k4b6b2a4b2b2b1e2e1a4b4c3j25d2a1f2c3a4d4c3
+AUXINFO :838:bd75eb5f7b129109b5cdcff0925c77ca5c0a135365002b93b44c5013c7a307b9504affcfb8ad934263196fc3e6d0b023abe48d254d46d29520e50a5e423c0fb1bc01ccc51cad61045c439e7c2bb8e5788bc7f3622aaa3a8125ebde11c9cd69b6f2393246fd094ad91e81ae58cd557b73bd1c9839cfad5835c8519e44298204eaca58dfd79289546959bfbabdc5f3cb7a27b8d3fb2d0b062bd5c2e469493c19f8c89989df73d8a3ab02d9afcbfedf245306d15881a01d153122f8374c7526abecc90919f99ff62e9789cabc402249af095ceb14c8c59c0d9ffbcdd731d50114e7c30c31ef0638f4d352abbfd04b4315d368d65bbfe005b6586245bc5244e5050098cf4c1b6986120f40d5ce038c10a3f309286f950cdc287e495aa13c70ab0c1f113a135556d7ce895fd8244afcbad43fe51f275837f223a1cb95151de8a158cb0add7fa8c9f1fa0e09a1ce842136c1679144cead56b164c4ef1a09ed36fd9704ba191b5957bc3d5bb97d8a1f7451d357a6638ac320b0beb0cd35aa404c8f1621c6d400960aa97bf6ce3a944339d7e401c4d98c31773b2a8881352d5653fdb5e8f7c04b
+NSTATES :2:63
+STATEPOS:2:41
+MOVE :10:L8,0,5,0,1
+MOVE :10:L8,0,5,0,2
+MOVE :10:L8,0,8,2,1
+MOVE :10:L8,0,8,2,2
+MOVE :4:M8,0
+MOVE :10:L0,2,3,2,1
+MOVE :10:L0,2,3,2,2
+MOVE :10:L0,2,0,7,1
+MOVE :10:L0,2,0,7,2
+MOVE :4:M0,2
+MOVE :10:L1,0,3,0,1
+MOVE :4:M1,0
+MOVE :10:L3,0,5,0,1
+MOVE :10:L3,0,3,2,1
+MOVE :10:L1,3,1,5,1
+MOVE :10:L0,7,5,7,1
+MOVE :10:L0,7,0,9,1
+MOVE :10:L0,9,5,9,1
+MOVE :10:L0,9,5,9,2
+MOVE :10:L0,9,0,7,2
+MOVE :4:M0,9
+MOVE :4:M0,7
+MOVE :10:L4,8,8,8,1
+MOVE :10:L4,8,8,8,2
+MOVE :4:M4,8
+MOVE :10:L5,9,9,9,1
+MOVE :10:L5,9,9,9,2
+MOVE :4:M5,9
+MOVE :10:L9,9,9,6,1
+MOVE :4:M9,9
+MOVE :10:L8,8,8,5,1
+MOVE :4:M8,8
+MOVE :10:L9,6,9,4,1
+MOVE :4:M9,6
+MOVE :4:M9,4
+MOVE :10:L1,5,4,5,1
+MOVE :10:L1,5,4,5,2
+MOVE :10:L1,5,1,3,2
+MOVE :4:M1,3
+MOVE :4:M1,5
+MOVE :10:L3,4,3,2,1
+MOVE :10:L3,4,3,2,2
+MOVE :4:M3,4
+MOVE :10:L4,5,8,5,1
+MOVE :10:L7,7,5,7,1
+MOVE :4:M5,7
+MOVE :4:M7,7
+MOVE :10:L7,3,4,3,1
+MOVE :4:M7,3
+MOVE :10:L5,0,3,0,2
+MOVE :4:M5,0
+MOVE :4:M3,0
+MOVE :10:L3,2,6,2,1
+MOVE :4:M3,2
+MOVE :10:L6,2,8,2,1
+MOVE :4:M6,2
+MOVE :10:L8,2,8,5,1
+MOVE :4:M8,2
+MOVE :4:M8,5
+MOVE :10:L4,5,4,3,1
+MOVE :4:M4,3
+MOVE :4:M4,5
diff --git a/apps/plugins/puzzles/icons/cicon.pl b/apps/plugins/puzzles/icons/cicon.pl
new file mode 100755
index 0000000..3578bd3
--- /dev/null
+++ b/apps/plugins/puzzles/icons/cicon.pl
@@ -0,0 +1,27 @@
+#!/usr/bin/perl
+
+# Given a list of input PNGs, create a C source file file
+# containing a const array of XPMs, under the name `xpm_icon'.
+
+$k = 0;
+@xpms = ();
+foreach $f (@ARGV) {
+ # XPM format is generated directly by ImageMagick, so that's easy
+ # enough. We just have to adjust the declaration line so that it
+ # has the right name, linkage and storage class.
+ @lines = ();
+ open XPM, "convert $f xpm:- |";
+ push @lines, $_ while <XPM>;
+ close XPM;
+ die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/;
+ $lines[1] = "static const char *const xpm_icon_$k"."[] = {\n";
+ $k++;
+ push @xpms, @lines, "\n";
+}
+
+# Now output.
+foreach $line (@xpms) { print $line; }
+print "const char *const *const xpm_icons[] = {\n";
+for ($i = 0; $i < $k; $i++) { print " xpm_icon_$i,\n"; }
+print "};\n";
+print "const int n_xpm_icons = $k;\n";
diff --git a/apps/plugins/puzzles/icons/crop.sh b/apps/plugins/puzzles/icons/crop.sh
new file mode 100755
index 0000000..0d15d3c
--- /dev/null
+++ b/apps/plugins/puzzles/icons/crop.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+# Crop one image into another, after first checking that the source
+# image has the expected size in pixels.
+#
+# This is used in the Puzzles icon build scripts to construct icons
+# which are zoomed in on a particular sub-area of the puzzle's
+# basic screenshot. This way I can define crop areas in pixels,
+# while not having to worry too much that if I adjust the source
+# puzzle so as to alter the layout the crop area might start
+# hitting the wrong bit of picture. Most layout changes I can
+# conveniently imagine will also alter the overall image size, so
+# this script will give a build error and alert me to the fact that
+# I need to fiddle with the icon makefile.
+
+infile="$1"
+outfile="$2"
+insize="$3"
+crop="$4"
+
+# Special case: if no input size or crop parameter was specified at
+# all, we just copy the input to the output file.
+
+if test $# -lt 3; then
+ cp "$infile" "$outfile"
+ exit 0
+fi
+
+# Check the input image size.
+realsize=`identify -format %wx%h "$infile"`
+if test "x$insize" != "x$realsize"; then
+ echo "crop.sh: '$infile' has wrong initial size: $realsize != $insize" >&2
+ exit 1
+fi
+
+# And crop.
+convert -crop "$crop" "$infile" "$outfile"
diff --git a/apps/plugins/puzzles/icons/cube.sav b/apps/plugins/puzzles/icons/cube.sav
new file mode 100644
index 0000000..bb123f4
--- /dev/null
+++ b/apps/plugins/puzzles/icons/cube.sav
@@ -0,0 +1,22 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :4:Cube
+PARAMS :4:c4x4
+CPARAMS :4:c4x4
+SEED :15:125146248070163
+DESC :6:C461,3
+NSTATES :2:14
+STATEPOS:1:5
+MOVE :1:D
+MOVE :1:D
+MOVE :1:D
+MOVE :1:U
+MOVE :1:L
+MOVE :1:L
+MOVE :1:D
+MOVE :1:U
+MOVE :1:D
+MOVE :1:U
+MOVE :1:U
+MOVE :1:U
+MOVE :1:L
diff --git a/apps/plugins/puzzles/icons/dominosa.sav b/apps/plugins/puzzles/icons/dominosa.sav
new file mode 100644
index 0000000..5991f3e
--- /dev/null
+++ b/apps/plugins/puzzles/icons/dominosa.sav
@@ -0,0 +1,53 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Dominosa
+PARAMS :1:6
+CPARAMS :1:6
+DESC :56:55521461210004364611033535444421636022603153156422620503
+NSTATES :2:46
+STATEPOS:2:33
+MOVE :6:D18,19
+MOVE :6:E22,23
+MOVE :6:E22,30
+MOVE :5:E9,17
+MOVE :6:D38,46
+MOVE :6:E14,15
+MOVE :5:E6,14
+MOVE :6:E33,34
+MOVE :6:E34,42
+MOVE :6:E26,34
+MOVE :6:D34,35
+MOVE :6:E42,50
+MOVE :6:E16,24
+MOVE :4:D4,5
+MOVE :4:D6,7
+MOVE :6:D15,23
+MOVE :6:E17,25
+MOVE :6:D16,17
+MOVE :6:E11,12
+MOVE :6:D51,52
+MOVE :5:E3,11
+MOVE :6:D10,11
+MOVE :4:D2,3
+MOVE :6:E37,45
+MOVE :6:D49,50
+MOVE :6:D40,48
+MOVE :6:D25,26
+MOVE :6:D24,32
+MOVE :6:D33,41
+MOVE :6:D42,43
+MOVE :6:D27,28
+MOVE :6:E21,29
+MOVE :6:D31,39
+MOVE :6:D47,55
+MOVE :6:E13,21
+MOVE :6:E13,14
+MOVE :6:D12,13
+MOVE :6:D20,21
+MOVE :6:D14,22
+MOVE :6:D29,30
+MOVE :6:D36,37
+MOVE :6:D44,45
+MOVE :6:D53,54
+MOVE :4:D0,1
+MOVE :4:D8,9
diff --git a/apps/plugins/puzzles/icons/fifteen.sav b/apps/plugins/puzzles/icons/fifteen.sav
new file mode 100644
index 0000000..d81345a
--- /dev/null
+++ b/apps/plugins/puzzles/icons/fifteen.sav
@@ -0,0 +1,74 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Fifteen
+PARAMS :3:4x4
+CPARAMS :3:4x4
+SEED :15:307905346810973
+DESC :37:8,11,3,6,14,13,4,2,0,9,12,10,5,1,7,15
+NSTATES :2:66
+STATEPOS:2:47
+MOVE :4:M1,2
+MOVE :4:M1,3
+MOVE :4:M0,3
+MOVE :4:M0,1
+MOVE :4:M1,1
+MOVE :4:M1,2
+MOVE :4:M0,2
+MOVE :4:M0,0
+MOVE :4:M1,0
+MOVE :4:M1,1
+MOVE :4:M0,1
+MOVE :4:M0,0
+MOVE :4:M1,0
+MOVE :4:M3,0
+MOVE :4:M3,1
+MOVE :4:M1,1
+MOVE :4:M1,0
+MOVE :4:M3,0
+MOVE :4:M3,1
+MOVE :4:M1,1
+MOVE :4:M1,0
+MOVE :4:M2,0
+MOVE :4:M2,1
+MOVE :4:M1,1
+MOVE :4:M1,3
+MOVE :4:M0,3
+MOVE :4:M0,1
+MOVE :4:M1,1
+MOVE :4:M1,2
+MOVE :4:M0,2
+MOVE :4:M0,1
+MOVE :4:M2,1
+MOVE :4:M3,1
+MOVE :4:M3,2
+MOVE :4:M2,2
+MOVE :4:M2,3
+MOVE :4:M3,3
+MOVE :4:M3,1
+MOVE :4:M2,1
+MOVE :4:M2,2
+MOVE :4:M1,2
+MOVE :4:M1,3
+MOVE :4:M2,3
+MOVE :4:M2,2
+MOVE :4:M1,2
+MOVE :4:M0,2
+MOVE :4:M0,3
+MOVE :4:M1,3
+MOVE :4:M1,2
+MOVE :4:M2,2
+MOVE :4:M2,3
+MOVE :4:M0,3
+MOVE :4:M0,2
+MOVE :4:M1,2
+MOVE :4:M2,2
+MOVE :4:M2,3
+MOVE :4:M1,3
+MOVE :4:M1,2
+MOVE :4:M3,2
+MOVE :4:M3,3
+MOVE :4:M1,3
+MOVE :4:M1,2
+MOVE :4:M2,2
+MOVE :4:M2,3
+MOVE :4:M3,3
diff --git a/apps/plugins/puzzles/icons/filling.sav b/apps/plugins/puzzles/icons/filling.sav
new file mode 100644
index 0000000..caf0bb2
--- /dev/null
+++ b/apps/plugins/puzzles/icons/filling.sav
@@ -0,0 +1,38 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Filling
+PARAMS :3:7x7
+CPARAMS :3:7x7
+SEED :15:279172739852696
+DESC :49:0000000031051240010004000001106171000400001013105
+NSTATES :2:30
+STATEPOS:2:13
+MOVE :4:38_3
+MOVE :4:39_3
+MOVE :4:36_4
+MOVE :4:43_4
+MOVE :4:35_4
+MOVE :4:47_5
+MOVE :4:40_5
+MOVE :4:34_5
+MOVE :4:41_5
+MOVE :4:25_7
+MOVE :4:23_6
+MOVE :4:16_6
+MOVE :4:18_7
+MOVE :4:19_7
+MOVE :4:20_7
+MOVE :4:26_7
+MOVE :4:24_7
+MOVE :4:29_6
+MOVE :4:22_6
+MOVE :4:15_6
+MOVE :3:7_4
+MOVE :3:0_4
+MOVE :3:1_3
+MOVE :3:2_3
+MOVE :3:6_2
+MOVE :3:5_5
+MOVE :3:4_5
+MOVE :3:3_5
+MOVE :4:10_5
diff --git a/apps/plugins/puzzles/icons/flip.sav b/apps/plugins/puzzles/icons/flip.sav
new file mode 100644
index 0000000..82b4c49
--- /dev/null
+++ b/apps/plugins/puzzles/icons/flip.sav
@@ -0,0 +1,20 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :4:Flip
+PARAMS :4:5x5c
+CPARAMS :4:5x5c
+SEED :15:158897339725978
+DESC :165:c400007100001c4000071000018400043100011c400047100011c400046100010c400047100011c4000471000118400043100011c400047100011c400046100010c000047000011c0000470000118,5c18b48
+NSTATES :2:12
+STATEPOS:1:4
+MOVE :4:M4,3
+MOVE :4:M3,0
+MOVE :4:M2,2
+MOVE :4:M3,2
+MOVE :4:M2,3
+MOVE :4:M0,2
+MOVE :4:M0,3
+MOVE :4:M1,4
+MOVE :4:M0,0
+MOVE :4:M1,0
+MOVE :4:M1,1
diff --git a/apps/plugins/puzzles/icons/flood.sav b/apps/plugins/puzzles/icons/flood.sav
new file mode 100644
index 0000000..ac4adf7
--- /dev/null
+++ b/apps/plugins/puzzles/icons/flood.sav
@@ -0,0 +1,14 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Flood
+PARAMS :7:6x6c6m5
+CPARAMS :7:6x6c6m5
+SEED :15:967543368167853
+DESC :39:032242034203340350204502505323231342,17
+NSTATES :1:6
+STATEPOS:1:6
+MOVE :2:M3
+MOVE :2:M2
+MOVE :2:M0
+MOVE :2:M5
+MOVE :2:M3
diff --git a/apps/plugins/puzzles/icons/galaxies.sav b/apps/plugins/puzzles/icons/galaxies.sav
new file mode 100644
index 0000000..42d18bc
--- /dev/null
+++ b/apps/plugins/puzzles/icons/galaxies.sav
@@ -0,0 +1,51 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Galaxies
+PARAMS :5:7x7dh
+CPARAMS :5:7x7dh
+SEED :15:483644862786314
+DESC :13:ikrqfedzljjsp
+NSTATES :2:43
+STATEPOS:2:37
+MOVE :5:E12,9
+MOVE :5:E8,11
+MOVE :5:E5,12
+MOVE :5:E7,12
+MOVE :5:E4,13
+MOVE :5:E2,11
+MOVE :5:E3,10
+MOVE :4:E2,5
+MOVE :4:E4,5
+MOVE :4:E6,7
+MOVE :4:E8,1
+MOVE :5:E10,1
+MOVE :4:E9,2
+MOVE :4:E6,3
+MOVE :4:E7,4
+MOVE :5:E10,3
+MOVE :5:E10,5
+MOVE :5:E11,6
+MOVE :5:E13,6
+MOVE :5:E8,13
+MOVE :5:E12,7
+MOVE :6:E12,11
+MOVE :6:E13,12
+MOVE :4:E8,9
+MOVE :4:E7,8
+MOVE :4:E7,6
+MOVE :4:E9,6
+MOVE :4:E8,5
+MOVE :4:E9,4
+MOVE :4:E5,2
+MOVE :4:E4,1
+MOVE :4:E3,6
+MOVE :4:E2,7
+MOVE :4:E3,8
+MOVE :4:E3,4
+MOVE :4:E4,9
+MOVE :4:E2,9
+MOVE :5:E5,10
+MOVE :5:E6,11
+MOVE :4:E2,3
+MOVE :4:E2,1
+MOVE :5:E1,12
diff --git a/apps/plugins/puzzles/icons/guess.sav b/apps/plugins/puzzles/icons/guess.sav
new file mode 100644
index 0000000..69852bf
--- /dev/null
+++ b/apps/plugins/puzzles/icons/guess.sav
@@ -0,0 +1,15 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Guess
+PARAMS :9:c6p4g10Bm
+CPARAMS :9:c6p4g10Bm
+SEED :15:313100730915729
+DESC :8:b5f3faed
+UI :7:0,0,0,0
+NSTATES :1:6
+STATEPOS:1:6
+MOVE :8:G1,1,2,2
+MOVE :8:G4,3,1,1
+MOVE :8:G5,5,1,1
+MOVE :8:G4,2,1,6
+MOVE :8:G2,3,1,6
diff --git a/apps/plugins/puzzles/icons/icon.pl b/apps/plugins/puzzles/icons/icon.pl
new file mode 100755
index 0000000..fcb1aa3
--- /dev/null
+++ b/apps/plugins/puzzles/icons/icon.pl
@@ -0,0 +1,270 @@
+#!/usr/bin/perl
+
+# Take a collection of input image files and convert them into a
+# multi-resolution Windows .ICO icon file.
+#
+# The input images can be treated as having four different colour
+# depths:
+#
+# - 24-bit true colour
+# - 8-bit with custom palette
+# - 4-bit using the Windows 16-colour palette (see comment below
+# for details)
+# - 1-bit using black and white only.
+#
+# The images can be supplied in any input format acceptable to
+# ImageMagick, but their actual colour usage must already be
+# appropriate for the specified mode; this script will not do any
+# substantive conversion. So if an image intended to be used in 4-
+# or 1-bit mode contains any colour not in the appropriate fixed
+# palette, that's a fatal error; if an image to be used in 8-bit
+# mode contains more than 256 distinct colours, that's also a fatal
+# error.
+#
+# Command-line syntax is:
+#
+# icon.pl -depth imagefile [imagefile...] [-depth imagefile [imagefile...]]
+#
+# where `-depth' is one of `-24', `-8', `-4' or `-1', and tells the
+# script how to treat all the image files given after that option
+# until the next depth option. For example, you might execute
+#
+# icon.pl -24 48x48x24.png 32x32x24.png -8 32x32x8.png -1 monochrome.png
+#
+# to build an icon file containing two differently sized 24-bit
+# images, one 8-bit image and one black and white image.
+#
+# Windows .ICO files support a 1-bit alpha channel on all these
+# image types. That is, any pixel can be either opaque or fully
+# transparent, but not partially transparent. The alpha channel is
+# separate from the main image data, meaning that `transparent' is
+# not required to take up a palette entry. (So an 8-bit image can
+# have 256 distinct _opaque_ colours, plus transparent pixels as
+# well.) If the input images have alpha channels, they will be used
+# to determine which pixels of the icon are transparent, by simple
+# quantisation half way up (e.g. in a PNG image with an 8-bit alpha
+# channel, alpha values of 00-7F will be mapped to transparent
+# pixels, and 80-FF will become opaque).
+
+# The Windows 16-colour palette consists of:
+# - the eight corners of the colour cube (000000, 0000FF, 00FF00,
+# 00FFFF, FF0000, FF00FF, FFFF00, FFFFFF)
+# - dim versions of the seven non-black corners, at 128/255 of the
+# brightness (000080, 008000, 008080, 800000, 800080, 808000,
+# 808080)
+# - light grey at 192/255 of full brightness (C0C0C0).
+%win16pal = (
+ "\x00\x00\x00\x00" => 0,
+ "\x00\x00\x80\x00" => 1,
+ "\x00\x80\x00\x00" => 2,
+ "\x00\x80\x80\x00" => 3,
+ "\x80\x00\x00\x00" => 4,
+ "\x80\x00\x80\x00" => 5,
+ "\x80\x80\x00\x00" => 6,
+ "\xC0\xC0\xC0\x00" => 7,
+ "\x80\x80\x80\x00" => 8,
+ "\x00\x00\xFF\x00" => 9,
+ "\x00\xFF\x00\x00" => 10,
+ "\x00\xFF\xFF\x00" => 11,
+ "\xFF\x00\x00\x00" => 12,
+ "\xFF\x00\xFF\x00" => 13,
+ "\xFF\xFF\x00\x00" => 14,
+ "\xFF\xFF\xFF\x00" => 15,
+);
+@win16pal = sort { $win16pal{$a} <=> $win16pal{$b} } keys %win16pal;
+
+# The black and white palette consists of black (000000) and white
+# (FFFFFF), obviously.
+%win2pal = (
+ "\x00\x00\x00\x00" => 0,
+ "\xFF\xFF\xFF\x00" => 1,
+);
+@win2pal = sort { $win16pal{$a} <=> $win2pal{$b} } keys %win2pal;
+
+@hdr = ();
+@dat = ();
+
+$depth = undef;
+foreach $_ (@ARGV) {
+ if (/^-(24|8|4|1)$/) {
+ $depth = $1;
+ } elsif (defined $depth) {
+ &readicon($_, $depth);
+ } else {
+ $usage = 1;
+ }
+}
+if ($usage || length @hdr == 0) {
+ print "usage: icon.pl ( -24 | -8 | -4 | -1 ) image [image...]\n";
+ print " [ ( -24 | -8 | -4 | -1 ) image [image...] ...]\n";
+ exit 0;
+}
+
+# Now write out the output icon file.
+print pack "vvv", 0, 1, scalar @hdr; # file-level header
+$filepos = 6 + 16 * scalar @hdr;
+for ($i = 0; $i < scalar @hdr; $i++) {
+ print $hdr[$i];
+ print pack "V", $filepos;
+ $filepos += length($dat[$i]);
+}
+for ($i = 0; $i < scalar @hdr; $i++) {
+ print $dat[$i];
+}
+
+sub readicon {
+ my $filename = shift @_;
+ my $depth = shift @_;
+ my $pix;
+ my $i;
+ my %pal;
+
+ # Determine the icon's width and height.
+ my $w = `identify -format %w $filename`;
+ my $h = `identify -format %h $filename`;
+
+ # Read the file in as RGBA data. We flip vertically at this
+ # point, to avoid having to do it ourselves (.BMP and hence
+ # .ICO are bottom-up).
+ my $data = [];
+ open IDATA, "convert -set colorspace sRGB -flip -depth 8 $filename rgba:- |";
+ push @$data, $rgb while (read IDATA,$rgb,4,0) == 4;
+ close IDATA;
+ # Check we have the right amount of data.
+ $xl = $w * $h;
+ $al = scalar @$data;
+ die "wrong amount of image data ($al, expected $xl) from $filename\n"
+ unless $al == $xl;
+
+ # Build the alpha channel now, so we can exclude transparent
+ # pixels from the palette analysis. We replace transparent
+ # pixels with undef in the data array.
+ #
+ # We quantise the alpha channel half way up, so that alpha of
+ # 0x80 or more is taken to be fully opaque and 0x7F or less is
+ # fully transparent. Nasty, but the best we can do without
+ # dithering (and don't even suggest we do that!).
+ my $x;
+ my $y;
+ my $alpha = "";
+
+ for ($y = 0; $y < $h; $y++) {
+ my $currbyte = 0, $currbits = 0;
+ for ($x = 0; $x < (($w+31)|31)-31; $x++) {
+ $pix = ($x < $w ? $data->[$y*$w+$x] : "\x00\x00\x00\xFF");
+ my @rgba = unpack "CCCC", $pix;
+ $currbyte <<= 1;
+ $currbits++;
+ if ($rgba[3] < 0x80) {
+ if ($x < $w) {
+ $data->[$y*$w+$x] = undef;
+ }
+ $currbyte |= 1; # MS has the alpha channel inverted :-)
+ } else {
+ # Might as well flip RGBA into BGR0 while we're here.
+ if ($x < $w) {
+ $data->[$y*$w+$x] = pack "CCCC",
+ $rgba[2], $rgba[1], $rgba[0], 0;
+ }
+ }
+ if ($currbits >= 8) {
+ $alpha .= pack "C", $currbyte;
+ $currbits -= 8;
+ }
+ }
+ }
+
+ # For an 8-bit image, check we have at most 256 distinct
+ # colours, and build the palette.
+ %pal = ();
+ if ($depth == 8) {
+ my $palindex = 0;
+ foreach $pix (@$data) {
+ next unless defined $pix;
+ $pal{$pix} = $palindex++ unless defined $pal{$pix};
+ }
+ die "too many colours in 8-bit image $filename\n" unless $palindex <= 256;
+ } elsif ($depth == 4) {
+ %pal = %win16pal;
+ } elsif ($depth == 1) {
+ %pal = %win2pal;
+ }
+
+ my $raster = "";
+ if ($depth < 24) {
+ # For a non-24-bit image, flatten the image into one palette
+ # index per pixel.
+ $pad = 32 / $depth; # number of pixels to pad scanline to 4-byte align
+ $pmask = $pad-1;
+ for ($y = 0; $y < $h; $y++) {
+ my $currbyte = 0, $currbits = 0;
+ for ($x = 0; $x < (($w+$pmask)|$pmask)-$pmask; $x++) {
+ $currbyte <<= $depth;
+ $currbits += $depth;
+ if ($x < $w && defined ($pix = $data->[$y*$w+$x])) {
+ if (!defined $pal{$pix}) {
+ my $pixprintable = unpack "H*", $pix;
+ die "illegal colour value $pixprintable at pixel ($x,$y) in $filename\n";
+ }
+ $currbyte |= $pal{$pix};
+ }
+ if ($currbits >= 8) {
+ $raster .= pack "C", $currbyte;
+ $currbits -= 8;
+ }
+ }
+ }
+ } else {
+ # For a 24-bit image, reverse the order of the R,G,B values
+ # and stick a padding zero on the end.
+ #
+ # (In this loop we don't need to bother padding the
+ # scanline out to a multiple of four bytes, because every
+ # pixel takes four whole bytes anyway.)
+ for ($i = 0; $i < scalar @$data; $i++) {
+ if (defined $data->[$i]) {
+ $raster .= $data->[$i];
+ } else {
+ $raster .= "\x00\x00\x00\x00";
+ }
+ }
+ $depth = 32; # and adjust this
+ }
+
+ # Prepare the icon data. First the header...
+ my $data = pack "VVVvvVVVVVV",
+ 40, # size of bitmap info header
+ $w, # icon width
+ $h*2, # icon height (x2 to indicate the subsequent alpha channel)
+ 1, # 1 plane (common to all MS image formats)
+ $depth, # bits per pixel
+ 0, # no compression
+ length $raster, # image size
+ 0, 0, 0, 0; # resolution, colours used, colours important (ignored)
+ # ... then the palette ...
+ if ($depth <= 8) {
+ my $ncols = (1 << $depth);
+ my $palette = "\x00\x00\x00\x00" x $ncols;
+ foreach $i (keys %pal) {
+ substr($palette, $pal{$i}*4, 4) = $i;
+ }
+ $data .= $palette;
+ }
+ # ... the raster data we already had ready ...
+ $data .= $raster;
+ # ... and the alpha channel we already had as well.
+ $data .= $alpha;
+
+ # Prepare the header which will represent this image in the
+ # icon file.
+ my $header = pack "CCCCvvV",
+ $w, $h, # width and height (this time the real height)
+ 1 << $depth, # number of colours, if less than 256
+ 0, # reserved
+ 1, # planes
+ $depth, # bits per pixel
+ length $data; # size of real icon data
+
+ push @hdr, $header;
+ push @dat, $data;
+}
diff --git a/apps/plugins/puzzles/icons/inertia.sav b/apps/plugins/puzzles/icons/inertia.sav
new file mode 100644
index 0000000..a6d6fae
--- /dev/null
+++ b/apps/plugins/puzzles/icons/inertia.sav
@@ -0,0 +1,30 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Inertia
+PARAMS :3:8x8
+CPARAMS :3:8x8
+SEED :15:739970145068932
+DESC :64:sbgwsmswwgggwggmmbwgwbssbwbsbwbbwsSmgbbsbbmsgbmssgmggbmmwmbmmwsw
+UI :2:D0
+NSTATES :2:21
+STATEPOS:1:5
+MOVE :1:6
+MOVE :1:5
+MOVE :1:3
+MOVE :1:1
+MOVE :1:6
+MOVE :1:0
+MOVE :1:5
+MOVE :1:7
+MOVE :1:5
+MOVE :1:6
+MOVE :1:1
+MOVE :1:3
+MOVE :1:4
+MOVE :1:2
+MOVE :1:6
+MOVE :1:5
+MOVE :1:3
+MOVE :1:1
+MOVE :1:5
+MOVE :1:3
diff --git a/apps/plugins/puzzles/icons/keen.sav b/apps/plugins/puzzles/icons/keen.sav
new file mode 100644
index 0000000..4adbd42
--- /dev/null
+++ b/apps/plugins/puzzles/icons/keen.sav
@@ -0,0 +1,62 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :4:Keen
+PARAMS :3:5de
+CPARAMS :3:5de
+SEED :15:846699649745236
+DESC :48:a__a_3a_5a_a_a_3b_bac_,a5m15a7a10s2s2d2s3m40m2s2
+AUXINFO :52:6105af67c6ebc8de056b59ebc9a463aa54e75f647055c0a6c1bd
+NSTATES :2:53
+STATEPOS:2:39
+MOVE :6:P0,4,2
+MOVE :6:P0,4,4
+MOVE :6:P0,4,5
+MOVE :6:P1,4,2
+MOVE :6:P1,4,4
+MOVE :6:P1,4,5
+MOVE :6:P1,3,2
+MOVE :6:P1,3,4
+MOVE :6:P1,3,5
+MOVE :6:R2,2,4
+MOVE :6:R1,2,2
+MOVE :6:P1,3,2
+MOVE :6:P1,4,2
+MOVE :6:R0,4,2
+MOVE :6:R2,3,2
+MOVE :6:R2,4,1
+MOVE :6:R1,4,4
+MOVE :6:R1,3,5
+MOVE :6:P3,4,3
+MOVE :6:P3,4,5
+MOVE :6:P4,4,3
+MOVE :6:P4,4,5
+MOVE :6:R4,4,5
+MOVE :6:R3,4,3
+MOVE :6:P3,1,2
+MOVE :6:P3,1,5
+MOVE :6:P3,0,2
+MOVE :6:P3,0,5
+MOVE :6:R3,2,1
+MOVE :6:R3,3,4
+MOVE :6:P2,0,3
+MOVE :6:P2,0,5
+MOVE :6:P2,1,3
+MOVE :6:P2,1,5
+MOVE :6:P0,1,1
+MOVE :6:P0,1,3
+MOVE :6:P1,1,1
+MOVE :6:P1,1,3
+MOVE :6:R2,0,3
+MOVE :6:R2,1,5
+MOVE :6:R3,0,5
+MOVE :6:R3,1,2
+MOVE :6:R4,1,4
+MOVE :6:R4,2,3
+MOVE :6:R4,0,2
+MOVE :6:R4,3,1
+MOVE :6:R0,2,5
+MOVE :6:R0,3,3
+MOVE :6:R1,1,3
+MOVE :6:R0,1,1
+MOVE :6:R1,0,1
+MOVE :6:R0,0,4
diff --git a/apps/plugins/puzzles/icons/lightup.sav b/apps/plugins/puzzles/icons/lightup.sav
new file mode 100644
index 0000000..21b59bd
--- /dev/null
+++ b/apps/plugins/puzzles/icons/lightup.sav
@@ -0,0 +1,24 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Light Up
+PARAMS :10:7x7b20s4d1
+CPARAMS :10:7x7b25s4d1
+SEED :15:538922615851330
+DESC :25:b3gB0c0dBaBaBa1aBd1c01g0b
+NSTATES :2:16
+STATEPOS:2:16
+MOVE :4:L1,0
+MOVE :4:L2,1
+MOVE :4:L3,0
+MOVE :4:L0,3
+MOVE :4:L6,1
+MOVE :4:L3,4
+MOVE :4:I6,5
+MOVE :4:I1,5
+MOVE :4:I2,6
+MOVE :4:I3,6
+MOVE :4:I4,5
+MOVE :4:I5,6
+MOVE :4:L5,5
+MOVE :4:I6,4
+MOVE :4:I4,2
diff --git a/apps/plugins/puzzles/icons/loopy.sav b/apps/plugins/puzzles/icons/loopy.sav
new file mode 100644
index 0000000..1161181
--- /dev/null
+++ b/apps/plugins/puzzles/icons/loopy.sav
@@ -0,0 +1,120 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Loopy
+PARAMS :7:7x7t0de
+CPARAMS :7:7x7t0de
+DESC :31:02g222b3b2e2a2b322b2a2a3a2a1d1b
+NSTATES :3:113
+STATEPOS:2:75
+MOVE :2:3n
+MOVE :2:0n
+MOVE :2:1n
+MOVE :2:2n
+MOVE :2:4n
+MOVE :2:6y
+MOVE :2:5y
+MOVE :3:25n
+MOVE :2:9n
+MOVE :3:28y
+MOVE :3:27y
+MOVE :3:42n
+MOVE :3:30n
+MOVE :3:45y
+MOVE :3:44y
+MOVE :3:59n
+MOVE :3:47n
+MOVE :3:62y
+MOVE :3:61y
+MOVE :3:76n
+MOVE :3:64n
+MOVE :3:79y
+MOVE :3:78y
+MOVE :3:93n
+MOVE :3:81n
+MOVE :4:110y
+MOVE :4:111y
+MOVE :3:99y
+MOVE :3:98y
+MOVE :3:24n
+MOVE :3:39y
+MOVE :3:23y
+MOVE :3:22y
+MOVE :3:26n
+MOVE :3:37n
+MOVE :3:38y
+MOVE :3:54n
+MOVE :3:69y
+MOVE :3:53y
+MOVE :3:40y
+MOVE :2:7y
+MOVE :3:88y
+MOVE :3:87y
+MOVE :4:102n
+MOVE :3:90n
+MOVE :3:52n
+MOVE :3:41y
+MOVE :3:55n
+MOVE :3:43n
+MOVE :2:8n
+MOVE :3:10y
+MOVE :3:12y
+MOVE :3:11n
+MOVE :3:13y
+MOVE :3:29n
+MOVE :3:15y
+MOVE :3:14n
+MOVE :3:16y
+MOVE :3:32y
+MOVE :3:31n
+MOVE :3:18y
+MOVE :3:17n
+MOVE :3:19y
+MOVE :3:20y
+MOVE :3:21n
+MOVE :3:33y
+MOVE :3:35y
+MOVE :3:36n
+MOVE :3:50y
+MOVE :3:57y
+MOVE :3:58y
+MOVE :3:72n
+MOVE :3:60n
+MOVE :3:74y
+MOVE :4:104y
+MOVE :4:107n
+MOVE :4:106n
+MOVE :3:92n
+MOVE :4:109n
+MOVE :3:89y
+MOVE :3:77n
+MOVE :3:75n
+MOVE :3:73y
+MOVE :3:85n
+MOVE :3:70n
+MOVE :3:56y
+MOVE :3:67n
+MOVE :3:71y
+MOVE :3:68y
+MOVE :3:84n
+MOVE :3:82n
+MOVE :3:83y
+MOVE :3:97n
+MOVE :3:86y
+MOVE :4:101y
+MOVE :4:100n
+MOVE :4:103y
+MOVE :4:105y
+MOVE :4:108y
+MOVE :3:96n
+MOVE :3:95y
+MOVE :3:94y
+MOVE :3:91y
+MOVE :3:80y
+MOVE :3:66n
+MOVE :3:65y
+MOVE :3:63y
+MOVE :3:51n
+MOVE :3:46n
+MOVE :3:34y
+MOVE :3:48n
+MOVE :3:49y
diff --git a/apps/plugins/puzzles/icons/magnets.sav b/apps/plugins/puzzles/icons/magnets.sav
new file mode 100644
index 0000000..3c317b7
--- /dev/null
+++ b/apps/plugins/puzzles/icons/magnets.sav
@@ -0,0 +1,33 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Magnets
+PARAMS :6:6x5dtS
+CPARAMS :6:6x5dtS
+SEED :15:705856238774945
+DESC :56:2.2..1,.3.2.,2.21..,2..0.,TLRTLRBLRBTTLRLRBBLRTTTTLRBBBB
+AUXINFO :60:ebae280db3eec279c628b6cfe4aca5a03ba24d7eba91169f1bdf275fce3f
+NSTATES :2:24
+STATEPOS:2:15
+MOVE :4:.1,3
+MOVE :4:.0,1
+MOVE :4:?0,1
+MOVE :4:.2,1
+MOVE :4:?2,1
+MOVE :4:.2,4
+MOVE :4:?2,4
+MOVE :4:+2,3
+MOVE :4:.3,3
+MOVE :4:.0,2
+MOVE :4:?0,2
+MOVE :4:+1,4
+MOVE :4:+0,2
+MOVE :4:+0,0
+MOVE :4:+1,1
+MOVE :4:.2,2
+MOVE :4:+2,0
+MOVE :4:+3,1
+MOVE :4:.4,0
+MOVE :4:+5,1
+MOVE :4:.5,3
+MOVE :4:+4,3
+MOVE :4:.4,2
diff --git a/apps/plugins/puzzles/icons/map.sav b/apps/plugins/puzzles/icons/map.sav
new file mode 100644
index 0000000..33863e1
--- /dev/null
+++ b/apps/plugins/puzzles/icons/map.sav
@@ -0,0 +1,27 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :3:Map
+PARAMS :10:20x20n30dn
+CPARAMS :10:20x20n30dn
+SEED :15:794003990129265
+DESC :264:dcbakatgcaaedaccabfabadbaaaagaiaaaeaiadcaaaafabccbdcaaecabggedfaebqbadgbngcblabdaadaaaeagabaaaacaacacbcaebabaabaebaafaaakabdhcdanaaceagakacbbajaaadbacbaaccbcbicdafbadgbaccbkcdaafbacbcaaabcddacaaaaddbabcdbbacabbhagajabbobcdjaecaafabahaaaffead,23a01c3c1a3d2a20b01a3a
+AUXINFO :282:738e7a68c5d32445002968f3726646962b3604ef27a3657e0fdc0fd8180d5b747febd4619487bbc8bec5a48c709b154eb8da39c9b49be1e312a381fc2394e53126714079bd82e8444dad92419429635d1c816c53774b8c77b4ce03884c94d12bfb757cd93b5600471cb9726b3f2afe74d9932abeaa2efd6a496cad793ce5b221f943d620e883794f9d56741908
+NSTATES :2:18
+STATEPOS:2:12
+MOVE :4:3:20
+MOVE :4:0:24
+MOVE :4:3:10
+MOVE :4:1:18
+MOVE :4:2:11
+MOVE :4:3:17
+MOVE :4:1:23
+MOVE :4:3:27
+MOVE :4:1:29
+MOVE :4:0:16
+MOVE :4:2:13
+MOVE :3:1:6
+MOVE :3:2:2
+MOVE :3:0:7
+MOVE :3:2:9
+MOVE :4:0:15
+MOVE :3:3:5
diff --git a/apps/plugins/puzzles/icons/mines.sav b/apps/plugins/puzzles/icons/mines.sav
new file mode 100644
index 0000000..a827541
--- /dev/null
+++ b/apps/plugins/puzzles/icons/mines.sav
@@ -0,0 +1,67 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Mines
+PARAMS :6:9x9n35
+CPARAMS :6:9x9n35
+SEED :15:698938038698621
+DESC :26:0,0,me0691ca8a278f3c371688
+PRIVDESC:22:me0691ca8a278f3c371688
+UI :3:D0C
+TIME :7:75.2958
+NSTATES :2:56
+STATEPOS:2:41
+MOVE :4:O0,0
+MOVE :4:F1,2
+MOVE :4:F0,2
+MOVE :4:O2,2
+MOVE :4:F2,1
+MOVE :4:F3,1
+MOVE :4:F3,2
+MOVE :4:F3,3
+MOVE :4:F1,3
+MOVE :4:F2,3
+MOVE :4:C1,0
+MOVE :4:C2,0
+MOVE :4:C3,0
+MOVE :4:F5,0
+MOVE :4:F5,1
+MOVE :4:C4,1
+MOVE :4:O6,1
+MOVE :4:O6,2
+MOVE :4:O6,3
+MOVE :4:F7,1
+MOVE :4:O7,4
+MOVE :4:O5,4
+MOVE :4:F5,3
+MOVE :4:F5,5
+MOVE :4:F6,6
+MOVE :4:C6,5
+MOVE :4:F8,6
+MOVE :4:C6,3
+MOVE :4:F8,2
+MOVE :4:C7,2
+MOVE :4:F8,0
+MOVE :4:F7,0
+MOVE :4:F6,0
+MOVE :4:C4,2
+MOVE :4:F4,4
+MOVE :4:F4,5
+MOVE :4:F3,4
+MOVE :4:C5,6
+MOVE :4:F7,7
+MOVE :4:F8,7
+MOVE :4:F7,8
+MOVE :4:O4,8
+MOVE :4:F3,6
+MOVE :4:C4,6
+MOVE :4:F3,8
+MOVE :4:F5,8
+MOVE :4:C6,7
+MOVE :4:C3,7
+MOVE :4:F2,5
+MOVE :4:F2,4
+MOVE :4:F1,8
+MOVE :4:F1,7
+MOVE :4:C2,7
+MOVE :4:C2,6
+MOVE :4:C1,6
diff --git a/apps/plugins/puzzles/icons/net.sav b/apps/plugins/puzzles/icons/net.sav
new file mode 100644
index 0000000..06a5426
--- /dev/null
+++ b/apps/plugins/puzzles/icons/net.sav
@@ -0,0 +1,53 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :3:Net
+PARAMS :3:5x5
+CPARAMS :3:5x5
+DESC :25:1115337157375775157135131
+UI :9:O0,0;C2,2
+NSTATES :2:45
+STATEPOS:2:45
+MOVE :4:C0,0
+MOVE :4:L0,0
+MOVE :4:L0,1
+MOVE :4:C0,2
+MOVE :4:L0,2
+MOVE :4:A0,3
+MOVE :4:L0,3
+MOVE :4:L0,4
+MOVE :4:L1,4
+MOVE :4:A2,4
+MOVE :4:A2,4
+MOVE :4:L2,4
+MOVE :4:C1,0
+MOVE :4:L1,0
+MOVE :4:L3,0
+MOVE :4:L2,0
+MOVE :4:A4,0
+MOVE :4:A4,0
+MOVE :4:L4,0
+MOVE :4:A4,1
+MOVE :4:L4,1
+MOVE :4:L3,1
+MOVE :4:A3,2
+MOVE :4:A3,2
+MOVE :4:L3,2
+MOVE :4:L2,2
+MOVE :4:A2,1
+MOVE :4:A2,1
+MOVE :4:A1,1
+MOVE :4:A1,1
+MOVE :4:A1,1
+MOVE :4:A1,1
+MOVE :4:A1,1
+MOVE :4:A1,1
+MOVE :4:A1,2
+MOVE :4:A1,2
+MOVE :4:A1,3
+MOVE :4:C2,3
+MOVE :4:A3,3
+MOVE :4:A4,4
+MOVE :4:A4,4
+MOVE :4:A4,3
+MOVE :4:A4,2
+MOVE :4:A4,2
diff --git a/apps/plugins/puzzles/icons/netslide.sav b/apps/plugins/puzzles/icons/netslide.sav
new file mode 100644
index 0000000..f37178e
--- /dev/null
+++ b/apps/plugins/puzzles/icons/netslide.sav
@@ -0,0 +1,47 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Netslide
+PARAMS :3:4x4
+CPARAMS :3:4x4
+SEED :15:344208514520242
+DESC :16:49b59aca247714b4
+AUXINFO :34:60d28a22f68cdb6078d67a4d6069b9ff54
+NSTATES :2:38
+STATEPOS:2:31
+MOVE :4:R0,1
+MOVE :4:C1,1
+MOVE :4:R1,1
+MOVE :4:R1,1
+MOVE :4:C3,1
+MOVE :4:C1,1
+MOVE :4:R1,1
+MOVE :4:R1,1
+MOVE :4:R3,1
+MOVE :4:R0,1
+MOVE :4:C1,1
+MOVE :5:R3,-1
+MOVE :5:R0,-1
+MOVE :4:R0,1
+MOVE :4:R0,1
+MOVE :4:C0,1
+MOVE :5:R0,-1
+MOVE :5:R0,-1
+MOVE :5:C1,-1
+MOVE :4:R1,1
+MOVE :4:C1,1
+MOVE :5:R1,-1
+MOVE :5:C0,-1
+MOVE :5:C0,-1
+MOVE :4:R3,1
+MOVE :4:C0,1
+MOVE :4:C0,1
+MOVE :5:R3,-1
+MOVE :4:C0,1
+MOVE :5:R3,-1
+MOVE :5:C1,-1
+MOVE :4:R0,1
+MOVE :4:C0,1
+MOVE :5:R0,-1
+MOVE :5:C0,-1
+MOVE :4:C1,1
+MOVE :4:R3,1
diff --git a/apps/plugins/puzzles/icons/palisade.sav b/apps/plugins/puzzles/icons/palisade.sav
new file mode 100644
index 0000000..a935e89
--- /dev/null
+++ b/apps/plugins/puzzles/icons/palisade.sav
@@ -0,0 +1,50 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Palisade
+PARAMS :5:5x5n5
+CPARAMS :5:5x5n5
+SEED :15:930059588777257
+DESC :13:2d23c33e2c1b2
+AUXINFO :52:14a191be1282597737537139d11d87fb4f21ad4a8f31e67b4441
+NSTATES :2:41
+STATEPOS:2:27
+MOVE :14:F0,1,16F0,0,64
+MOVE :15:F0,0,32F1,0,128
+MOVE :12:F1,1,8F0,1,2
+MOVE :12:F1,0,4F1,1,1
+MOVE :14:F0,2,16F0,1,64
+MOVE :12:F1,2,8F0,2,2
+MOVE :12:F0,3,1F0,2,4
+MOVE :15:F2,0,128F1,0,32
+MOVE :12:F2,0,4F2,1,1
+MOVE :12:F3,0,8F2,0,2
+MOVE :15:F1,4,128F0,4,32
+MOVE :14:F1,4,16F1,3,64
+MOVE :15:F2,4,128F1,4,32
+MOVE :14:F0,3,64F0,4,16
+MOVE :15:F1,3,128F0,3,32
+MOVE :12:F1,3,1F1,2,4
+MOVE :15:F4,4,128F3,4,32
+MOVE :14:F4,4,16F4,3,64
+MOVE :12:F3,4,8F2,4,2
+MOVE :12:F2,4,1F2,3,4
+MOVE :12:F2,3,8F1,3,2
+MOVE :14:F2,2,64F2,3,16
+MOVE :15:F2,3,32F3,3,128
+MOVE :12:F3,3,4F3,4,1
+MOVE :12:F4,3,8F3,3,2
+MOVE :14:F4,3,16F4,2,64
+MOVE :12:F1,2,1F1,1,4
+MOVE :15:F2,1,128F1,1,32
+MOVE :15:F2,2,128F1,2,32
+MOVE :12:F2,2,1F2,1,4
+MOVE :15:F3,2,128F2,2,32
+MOVE :14:F3,2,64F3,3,16
+MOVE :12:F4,2,8F3,2,2
+MOVE :12:F3,2,1F3,1,4
+MOVE :15:F2,1,32F3,1,128
+MOVE :14:F4,2,16F4,1,64
+MOVE :12:F4,1,8F3,1,2
+MOVE :14:F3,0,64F3,1,16
+MOVE :15:F4,0,128F3,0,32
+MOVE :12:F4,1,1F4,0,4
diff --git a/apps/plugins/puzzles/icons/pattern.sav b/apps/plugins/puzzles/icons/pattern.sav
new file mode 100644
index 0000000..97c2396
--- /dev/null
+++ b/apps/plugins/puzzles/icons/pattern.sav
@@ -0,0 +1,29 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Pattern
+PARAMS :5:10x10
+CPARAMS :5:10x10
+DESC :67:3.4/2.2/4.1/2.3/2.3.2/4/6/6/3.1/1/5/5/1.1/4/5/6/2.3/3.3/1.1.3/1.1.4
+NSTATES :2:22
+STATEPOS:2:22
+MOVE :8:F6,4,1,2
+MOVE :8:F7,4,1,2
+MOVE :8:F4,5,2,1
+MOVE :8:F5,4,1,1
+MOVE :8:E0,5,2,1
+MOVE :8:E0,4,3,1
+MOVE :8:F0,6,1,4
+MOVE :8:F0,1,1,2
+MOVE :8:F0,1,5,1
+MOVE :8:E1,2,1,1
+MOVE :8:F2,0,1,4
+MOVE :8:E3,2,1,1
+MOVE :8:F3,0,1,1
+MOVE :8:F4,0,1,1
+MOVE :8:F3,3,1,1
+MOVE :8:E6,3,4,1
+MOVE :8:F6,6,1,4
+MOVE :8:F7,6,1,4
+MOVE :8:E6,0,1,4
+MOVE :8:E7,0,1,3
+MOVE :8:E5,1,1,1
diff --git a/apps/plugins/puzzles/icons/pearl.sav b/apps/plugins/puzzles/icons/pearl.sav
new file mode 100644
index 0000000..730ca85
--- /dev/null
+++ b/apps/plugins/puzzles/icons/pearl.sav
@@ -0,0 +1,23 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Pearl
+PARAMS :5:6x6dt
+CPARAMS :5:6x6dt
+SEED :15:901944054393278
+DESC :17:BbBfWcWbWBaBeWgWa
+AUXINFO :72:f8bbe71b9be753d5fa143df207d7797ba62a9b3996eb8b8889487e1a2bd659d91a5e73e1
+NSTATES :2:14
+STATEPOS:1:7
+MOVE :55:F4,2,0;F1,1,0;F4,1,0;F1,0,0;F8,0,0;F2,0,1;F8,0,1;F2,0,2
+MOVE :27:F1,0,3;F4,1,3;F1,1,3;F4,2,3
+MOVE :27:F8,3,0;F2,3,1;F8,3,1;F2,3,2
+MOVE :97:F2,4,2;F8,4,1;F2,4,1;F8,4,0;F1,4,0;F4,5,0;F8,5,0;F2,5,1;F8,5,1;F2,5,2;F8,5,2;F2,5,3;F4,5,3;F1,4,3
+MOVE :13:F4,4,2;F1,3,2
+MOVE :13:F4,3,0;F1,2,0
+MOVE :69:F2,2,3;F8,2,2;F2,2,2;F8,2,1;F4,2,1;F1,1,1;F8,1,1;F2,1,2;F4,1,2;F1,0,2
+MOVE :41:F8,0,3;F2,0,4;F8,0,4;F2,0,5;F1,0,5;F4,1,5
+MOVE :27:F1,1,4;F4,2,4;F1,2,4;F4,3,4
+MOVE :13:F8,1,4;F2,1,5
+MOVE :55:F1,3,5;F4,4,5;F1,4,5;F4,5,5;F2,5,5;F8,5,4;F4,5,4;F1,4,4
+MOVE :13:F2,3,5;F8,3,4
+MOVE :13:F2,4,4;F8,4,3
diff --git a/apps/plugins/puzzles/icons/pegs.sav b/apps/plugins/puzzles/icons/pegs.sav
new file mode 100644
index 0000000..22b8a0d
--- /dev/null
+++ b/apps/plugins/puzzles/icons/pegs.sav
@@ -0,0 +1,16 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :4:Pegs
+PARAMS :8:7x7cross
+CPARAMS :8:7x7cross
+SEED :15:103342250484448
+DESC :49:OOPPPOOOOPPPOOPPPPPPPPPPHPPPPPPPPPPOOPPPOOOOPPPOO
+NSTATES :1:8
+STATEPOS:1:8
+MOVE :7:3,1-3,3
+MOVE :7:5,2-3,2
+MOVE :7:5,4-5,2
+MOVE :7:3,4-5,4
+MOVE :7:6,4-4,4
+MOVE :7:4,0-4,2
+MOVE :7:2,0-4,0
diff --git a/apps/plugins/puzzles/icons/range.sav b/apps/plugins/puzzles/icons/range.sav
new file mode 100644
index 0000000..708e7db
--- /dev/null
+++ b/apps/plugins/puzzles/icons/range.sav
@@ -0,0 +1,36 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Range
+PARAMS :3:7x7
+CPARAMS :3:7x7
+SEED :15:989032078841515
+DESC :22:d7b3e8e5c7a7c13e4e8b4d
+UI :1:0
+NSTATES :2:27
+STATEPOS:2:27
+MOVE :5:W,4,2
+MOVE :5:W,4,3
+MOVE :5:W,4,4
+MOVE :5:W,4,5
+MOVE :5:W,4,6
+MOVE :5:W,4,0
+MOVE :5:W,3,1
+MOVE :5:W,2,1
+MOVE :5:W,1,1
+MOVE :5:W,0,1
+MOVE :5:W,6,1
+MOVE :5:W,5,1
+MOVE :5:W,5,5
+MOVE :5:W,1,5
+MOVE :5:B,5,2
+MOVE :5:W,5,3
+MOVE :5:W,6,3
+MOVE :5:W,3,6
+MOVE :5:W,2,6
+MOVE :5:B,3,5
+MOVE :5:W,2,4
+MOVE :5:W,2,2
+MOVE :5:B,2,3
+MOVE :5:W,1,3
+MOVE :5:W,3,3
+MOVE :5:W,0,5
diff --git a/apps/plugins/puzzles/icons/rect.sav b/apps/plugins/puzzles/icons/rect.sav
new file mode 100644
index 0000000..17264da
--- /dev/null
+++ b/apps/plugins/puzzles/icons/rect.sav
@@ -0,0 +1,17 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :10:Rectangles
+PARAMS :3:7x7
+CPARAMS :3:7x7
+DESC :33:a3d2b2a3_2a4a8h2a3c4_2b2c3a3_3c3b
+NSTATES :2:10
+STATEPOS:2:10
+MOVE :8:R0,6,3,1
+MOVE :8:R6,4,1,3
+MOVE :8:R3,6,3,1
+MOVE :8:R4,4,2,1
+MOVE :8:R3,5,3,1
+MOVE :8:R6,1,1,3
+MOVE :8:R5,0,2,1
+MOVE :8:R5,1,1,2
+MOVE :8:R4,3,2,1
diff --git a/apps/plugins/puzzles/icons/samegame.sav b/apps/plugins/puzzles/icons/samegame.sav
new file mode 100644
index 0000000..f92b52d
--- /dev/null
+++ b/apps/plugins/puzzles/icons/samegame.sav
@@ -0,0 +1,34 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :9:Same Game
+PARAMS :9:10x10c3s2
+CPARAMS :9:10x10c3s2
+SEED :15:785412408200083
+DESC :199:1,1,3,1,2,2,1,2,3,2,2,2,3,3,2,1,1,1,3,2,3,3,2,3,1,3,2,1,1,3,1,2,2,2,3,2,3,2,3,2,1,3,1,2,1,2,3,2,1,3,2,3,1,1,3,3,1,3,3,3,1,1,3,2,2,1,1,2,1,2,2,2,3,1,3,2,2,1,2,3,3,1,2,3,1,3,3,2,1,3,3,1,3,1,2,2,1,3,1,2
+NSTATES :2:26
+STATEPOS:2:13
+MOVE :6:M94,95
+MOVE :6:M83,84
+MOVE :9:M83,93,94
+MOVE :6:M93,94
+MOVE :6:M20,21
+MOVE :15:M20,21,22,31,32
+MOVE :6:M70,71
+MOVE :6:M80,90
+MOVE :9:M73,82,83
+MOVE :18:M72,73,74,82,83,92
+MOVE :12:M51,61,62,72
+MOVE :9:M35,36,46
+MOVE :12:M49,57,58,59
+MOVE :6:M59,69
+MOVE :9:M69,79,89
+MOVE :12:M78,79,89,99
+MOVE :24:M45,46,47,54,55,57,64,67
+MOVE :36:M36,46,55,56,57,66,67,68,77,78,88,98
+MOVE :9:M76,77,87
+MOVE :6:M97,98
+MOVE :6:M94,95
+MOVE :45:M50,60,61,70,71,81,82,83,84,85,90,91,92,93,94
+MOVE :12:M73,81,82,83
+MOVE :6:M92,93
+MOVE :9:M81,90,91
diff --git a/apps/plugins/puzzles/icons/screenshot.sh b/apps/plugins/puzzles/icons/screenshot.sh
new file mode 100755
index 0000000..0e2a06e
--- /dev/null
+++ b/apps/plugins/puzzles/icons/screenshot.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Generate a screenshot from a puzzle save file. Takes the
+# following arguments, in order:
+#
+# - the name of the puzzle binary
+# - the name of the save file
+# - the name of the output image file
+# - (optionally) the proportion of the next move to redo before
+# taking the screenshot.
+#
+# This script requires access to an X server in order to run, but
+# seems to work fine under xvfb-run if you haven't got a real one
+# available (or if you don't want to use it for some reason).
+
+binary="$1"
+save="$2"
+image="$3"
+if test "x$4" != "x"; then
+ redo="--redo $4"
+else
+ redo=
+fi
+
+"$binary" $redo --screenshot "$image" --load "$save"
diff --git a/apps/plugins/puzzles/icons/signpost.sav b/apps/plugins/puzzles/icons/signpost.sav
new file mode 100644
index 0000000..9ad1958
--- /dev/null
+++ b/apps/plugins/puzzles/icons/signpost.sav
@@ -0,0 +1,23 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Signpost
+PARAMS :4:4x4c
+CPARAMS :4:4x4c
+SEED :15:230468784719861
+DESC :19:1eceebecfbfhgcaa16a
+NSTATES :2:15
+STATEPOS:2:11
+MOVE :8:L2,1-3,1
+MOVE :8:L0,1-1,0
+MOVE :8:L2,2-1,1
+MOVE :8:L1,2-0,3
+MOVE :8:L0,2-2,0
+MOVE :8:L1,3-1,2
+MOVE :8:L1,1-1,3
+MOVE :8:L1,0-3,0
+MOVE :8:L0,0-0,1
+MOVE :8:L3,0-3,2
+MOVE :8:L3,2-0,2
+MOVE :8:L3,1-2,2
+MOVE :8:L2,3-2,1
+MOVE :8:L2,0-2,3
diff --git a/apps/plugins/puzzles/icons/singles.sav b/apps/plugins/puzzles/icons/singles.sav
new file mode 100644
index 0000000..260fd1f
--- /dev/null
+++ b/apps/plugins/puzzles/icons/singles.sav
@@ -0,0 +1,45 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Singles
+PARAMS :5:6x6dk
+CPARAMS :5:6x6dk
+SEED :15:781273601054598
+DESC :36:361566412253452144234115163346553461
+NSTATES :2:37
+STATEPOS:2:22
+MOVE :4:B1,0
+MOVE :4:C0,0
+MOVE :4:C1,1
+MOVE :4:C2,0
+MOVE :4:C0,1
+MOVE :4:B0,2
+MOVE :4:C0,3
+MOVE :4:C1,2
+MOVE :4:C4,3
+MOVE :4:B3,3
+MOVE :4:C3,2
+MOVE :4:C2,3
+MOVE :4:C3,4
+MOVE :4:B2,4
+MOVE :4:C1,4
+MOVE :4:C2,5
+MOVE :4:B1,5
+MOVE :4:C0,5
+MOVE :4:C0,4
+MOVE :4:C1,3
+MOVE :4:C3,5
+MOVE :4:B5,4
+MOVE :4:C4,4
+MOVE :4:C5,5
+MOVE :4:C5,3
+MOVE :4:C4,5
+MOVE :4:B4,0
+MOVE :4:C3,0
+MOVE :4:C4,1
+MOVE :4:C5,0
+MOVE :4:C5,1
+MOVE :4:B4,2
+MOVE :4:C5,2
+MOVE :4:C3,1
+MOVE :4:B2,1
+MOVE :4:C2,2
diff --git a/apps/plugins/puzzles/icons/sixteen.sav b/apps/plugins/puzzles/icons/sixteen.sav
new file mode 100644
index 0000000..076b1fb
--- /dev/null
+++ b/apps/plugins/puzzles/icons/sixteen.sav
@@ -0,0 +1,39 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Sixteen
+PARAMS :3:4x4
+CPARAMS :3:4x4
+SEED :15:601798566229573
+DESC :38:2,16,3,10,13,8,7,4,9,14,12,11,15,1,5,6
+NSTATES :2:31
+STATEPOS:2:24
+MOVE :5:C3,-1
+MOVE :4:R0,1
+MOVE :4:C1,1
+MOVE :5:R0,-1
+MOVE :5:C1,-1
+MOVE :5:C3,-1
+MOVE :4:R2,1
+MOVE :4:R2,1
+MOVE :4:C3,1
+MOVE :5:C2,-1
+MOVE :5:C2,-1
+MOVE :4:R1,1
+MOVE :4:R1,1
+MOVE :4:C2,1
+MOVE :4:C2,1
+MOVE :4:R3,1
+MOVE :4:R3,1
+MOVE :4:C1,1
+MOVE :5:R2,-1
+MOVE :5:R2,-1
+MOVE :5:C1,-1
+MOVE :4:R2,1
+MOVE :4:C0,1
+MOVE :4:R3,1
+MOVE :5:R2,-1
+MOVE :5:C1,-1
+MOVE :4:R2,1
+MOVE :4:C1,1
+MOVE :5:R3,-1
+MOVE :5:C0,-1
diff --git a/apps/plugins/puzzles/icons/slant.sav b/apps/plugins/puzzles/icons/slant.sav
new file mode 100644
index 0000000..02017e5
--- /dev/null
+++ b/apps/plugins/puzzles/icons/slant.sav
@@ -0,0 +1,51 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Slant
+PARAMS :5:8x8de
+CPARAMS :5:8x8de
+DESC :47:a10h23a32a02b22e3a2c1g3a20d32a0c221a210i0a101b0
+NSTATES :2:44
+STATEPOS:2:44
+MOVE :4:/7,0
+MOVE :4:\7,1
+MOVE :4:\1,0
+MOVE :4:/2,0
+MOVE :4:\0,4
+MOVE :4:/0,5
+MOVE :4:\0,6
+MOVE :4:/0,7
+MOVE :4:\1,7
+MOVE :4:/7,7
+MOVE :4:/3,7
+MOVE :4:\4,7
+MOVE :4:\5,7
+MOVE :4:/2,7
+MOVE :4:/7,4
+MOVE :4:\7,5
+MOVE :4:\7,3
+MOVE :4:\7,2
+MOVE :4:/6,2
+MOVE :4:\6,3
+MOVE :4:\7,6
+MOVE :4:/3,0
+MOVE :4:/2,1
+MOVE :4:\3,1
+MOVE :4:/2,2
+MOVE :4:\3,2
+MOVE :4:/2,3
+MOVE :4:\3,3
+MOVE :4:\1,1
+MOVE :4:/0,1
+MOVE :4:\0,2
+MOVE :4:\1,2
+MOVE :4:\1,3
+MOVE :4:/0,3
+MOVE :4:\1,4
+MOVE :4:\0,0
+MOVE :4:\5,3
+MOVE :4:\6,4
+MOVE :4:/5,4
+MOVE :4:/5,5
+MOVE :4:\6,5
+MOVE :4:/4,5
+MOVE :4:\4,6
diff --git a/apps/plugins/puzzles/icons/solo.sav b/apps/plugins/puzzles/icons/solo.sav
new file mode 100644
index 0000000..385cc68
--- /dev/null
+++ b/apps/plugins/puzzles/icons/solo.sav
@@ -0,0 +1,36 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :4:Solo
+PARAMS :3:3x3
+CPARAMS :3:3x3
+DESC :73:a2e9a5b6a2b3_7a1_4a9_6a2b4_1a7_2b1_7e6_9b2_5a8_1b6a5_9a3_8a7_2b8a6b1a1e4a
+NSTATES :2:29
+STATEPOS:2:29
+MOVE :6:R7,1,1
+MOVE :6:R4,6,1
+MOVE :6:R5,0,1
+MOVE :6:R0,0,4
+MOVE :6:R2,0,6
+MOVE :6:R1,2,3
+MOVE :6:R0,3,9
+MOVE :6:R1,3,5
+MOVE :6:R2,4,8
+MOVE :6:R0,5,3
+MOVE :6:R1,5,6
+MOVE :6:R1,6,4
+MOVE :6:R4,7,4
+MOVE :6:R7,6,2
+MOVE :6:R7,7,5
+MOVE :6:R8,8,6
+MOVE :6:R7,3,3
+MOVE :6:R8,3,7
+MOVE :6:R8,3,8
+MOVE :6:R6,4,5
+MOVE :6:R7,5,7
+MOVE :6:R8,5,4
+MOVE :6:R7,2,8
+MOVE :6:R8,0,5
+MOVE :6:R4,2,5
+MOVE :6:R4,3,6
+MOVE :6:R5,4,4
+MOVE :6:R4,5,9
diff --git a/apps/plugins/puzzles/icons/square.pl b/apps/plugins/puzzles/icons/square.pl
new file mode 100755
index 0000000..815b94b
--- /dev/null
+++ b/apps/plugins/puzzles/icons/square.pl
@@ -0,0 +1,95 @@
+#!/usr/bin/perl
+
+# Read an input image, crop its border to a standard width, and
+# convert it into a square output image. Parameters are:
+#
+# - the required total image size
+# - the output border thickness
+# - the input image file name
+# - the output image file name.
+
+($osize, $oborder, $infile, $outfile) = @ARGV;
+
+# Determine the input image's size.
+$ident = `identify -format "%w %h" $infile`;
+$ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n";
+($w, $h) = ($1, $2);
+
+# Read the input image data.
+$data = [];
+open IDATA, "convert -depth 8 $infile rgb:- |";
+push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
+close IDATA;
+# Check we have the right amount of data.
+$xl = $w * $h;
+$al = scalar @$data;
+die "wrong amount of image data ($al, expected $xl) from $infile\n"
+ unless $al == $xl;
+
+# Find the background colour, by looking around the entire border
+# and finding the most popular pixel colour.
+for ($i = 0; $i < $w; $i++) {
+ $pcount{$data->[$i]}++; # top row
+ $pcount{$data->[($h-1)*$w+$i]}++; # bottom row
+}
+for ($i = 1; $i < $h-1; $i++) {
+ $pcount{$data->[$i*$w]}++; # left column
+ $pcount{$data->[$i*$w+$w-1]}++; # right column
+}
+@plist = sort { $pcount{$b} <=> $pcount{$a} } keys %pcount;
+$back = $plist[0];
+
+# Crop rows and columns off the image to find the central rectangle
+# of non-background stuff.
+$ystart = 0;
+$ystart++ while $ystart < $h and scalar(grep { $_ ne $back } map { $data->[$ystart*$w+$_] } 0 .. ($w-1)) == 0;
+$yend = $h-1;
+$yend-- while $yend >= $ystart and scalar(grep { $_ ne $back } map { $data->[$yend*$w+$_] } 0 .. ($w-1)) == 0;
+$xstart = 0;
+$xstart++ while $xstart < $w and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xstart] } 0 .. ($h-1)) == 0;
+$xend = $w-1;
+$xend-- while $xend >= $xstart and scalar(grep { $_ ne $back } map { $data->[$_*$w+$xend] } 0 .. ($h-1)) == 0;
+
+# Decide how much border we're going to put back on to make the
+# image perfectly square.
+$hexpand = ($yend-$ystart) - ($xend-$xstart);
+if ($hexpand > 0) {
+ $left = int($hexpand / 2);
+ $xstart -= $left;
+ $xend += $hexpand - $left;
+} elsif ($hexpand < 0) {
+ $vexpand = -$hexpand;
+ $top = int($vexpand / 2);
+ $ystart -= $top;
+ $yend += $vexpand - $top;
+}
+$ow = $xend - $xstart + 1;
+$oh = $yend - $ystart + 1;
+die "internal computation problem" if $ow != $oh; # should be square
+
+# And decide how much _more_ border goes on to add the bit around
+# the edge.
+$realow = int($ow * ($osize / ($osize - 2*$oborder)));
+$extra = $realow - $ow;
+$left = int($extra / 2);
+$xstart -= $left;
+$xend += $extra - $left;
+$top = int($extra / 2);
+$ystart -= $top;
+$yend += $extra - $top;
+$ow = $xend - $xstart + 1;
+$oh = $yend - $ystart + 1;
+die "internal computation problem" if $ow != $oh; # should be square
+
+# Now write out the resulting image, and resize it appropriately.
+open IDATA, "| convert -size ${ow}x${oh} -depth 8 -resize ${osize}x${osize}! rgb:- $outfile";
+for ($y = $ystart; $y <= $yend; $y++) {
+ for ($x = $xstart; $x <= $xend; $x++) {
+ if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {
+ print IDATA $data->[$y*$w+$x];
+ } else {
+ print IDATA $back;
+ }
+ }
+}
+close IDATA;
diff --git a/apps/plugins/puzzles/icons/tents.sav b/apps/plugins/puzzles/icons/tents.sav
new file mode 100644
index 0000000..292c2d2
--- /dev/null
+++ b/apps/plugins/puzzles/icons/tents.sav
@@ -0,0 +1,32 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :5:Tents
+PARAMS :5:8x8de
+CPARAMS :5:8x8de
+DESC :45:ea_ddidfaabkd,3,0,2,1,2,2,1,1,3,1,1,1,1,1,3,1
+NSTATES :2:25
+STATEPOS:2:25
+MOVE :9:N5,6;N6,6
+MOVE :14:N5,7;N6,7;N7,7
+MOVE :9:N0,7;N1,7
+MOVE :4:N1,6
+MOVE :14:N6,2;N6,3;N6,4
+MOVE :9:N7,2;N7,3
+MOVE :14:N1,0;N2,0;N3,0
+MOVE :4:N3,1
+MOVE :4:N0,3
+MOVE :4:N3,4
+MOVE :4:N5,4
+MOVE :4:T6,0
+MOVE :4:T4,0
+MOVE :4:T0,0
+MOVE :4:N1,1
+MOVE :4:N4,1
+MOVE :9:N6,1;N7,1
+MOVE :4:T2,1
+MOVE :9:N1,2;N3,2
+MOVE :4:T5,2
+MOVE :4:N4,2
+MOVE :4:N5,3
+MOVE :4:N0,2
+MOVE :9:N1,3;N1,5
diff --git a/apps/plugins/puzzles/icons/towers.sav b/apps/plugins/puzzles/icons/towers.sav
new file mode 100644
index 0000000..351d473
--- /dev/null
+++ b/apps/plugins/puzzles/icons/towers.sav
@@ -0,0 +1,26 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :6:Towers
+PARAMS :3:4de
+CPARAMS :3:4de
+SEED :15:888431554483015
+DESC :31:2/2/1/3/2/2/3/1/3/1/2/2/2/3/2/1
+AUXINFO :34:297d7a2fcf9e14403a74c976fe0fefd306
+NSTATES :2:17
+STATEPOS:2:10
+MOVE :6:R2,0,4
+MOVE :6:R0,1,4
+MOVE :6:R3,3,4
+MOVE :6:R1,2,4
+MOVE :6:R0,3,3
+MOVE :6:R1,0,3
+MOVE :6:R3,2,3
+MOVE :6:R2,1,3
+MOVE :6:R3,0,2
+MOVE :6:R3,1,1
+MOVE :6:R1,1,2
+MOVE :6:R1,3,1
+MOVE :6:R2,3,2
+MOVE :6:R2,2,1
+MOVE :6:R0,2,2
+MOVE :6:R0,0,1
diff --git a/apps/plugins/puzzles/icons/tracks.sav b/apps/plugins/puzzles/icons/tracks.sav
new file mode 100644
index 0000000..ca30644
--- /dev/null
+++ b/apps/plugins/puzzles/icons/tracks.sav
@@ -0,0 +1,31 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :12:Train Tracks
+PARAMS :5:6x6dt
+CPARAMS :5:6x6dt
+SEED :15:145870397370785
+DESC :31:l6t9b,3,2,1,S4,5,4,2,6,S3,2,3,3
+NSTATES :2:23
+STATEPOS:2:20
+MOVE :5:TD0,0
+MOVE :5:TR0,0
+MOVE :5:TL5,5
+MOVE :5:TU5,5
+MOVE :29:TS1,1;TS2,1;TS3,1;TS4,1;TS5,1
+MOVE :29:NS2,0;NS2,2;NS2,3;NS2,4;NS2,5
+MOVE :5:TU1,1
+MOVE :17:NS0,3;NS0,4;NS0,5
+MOVE :23:NS1,2;NS1,3;NS1,4;NS1,5
+MOVE :5:TL2,1
+MOVE :5:TL3,1
+MOVE :5:TS4,4
+MOVE :5:TS3,4
+MOVE :17:NS3,0;NS4,0;NS5,0
+MOVE :5:TS4,2
+MOVE :5:TS4,3
+MOVE :5:TU3,4
+MOVE :5:TL4,4
+MOVE :5:TL5,1
+MOVE :5:TU5,2
+MOVE :5:NS5,3
+MOVE :5:NS3,2
diff --git a/apps/plugins/puzzles/icons/twiddle.sav b/apps/plugins/puzzles/icons/twiddle.sav
new file mode 100644
index 0000000..2863033
--- /dev/null
+++ b/apps/plugins/puzzles/icons/twiddle.sav
@@ -0,0 +1,35 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Twiddle
+PARAMS :5:3x3n2
+CPARAMS :5:3x3n2
+SEED :15:635499951462226
+DESC :17:3,7,2,6,5,1,8,4,9
+NSTATES :2:27
+STATEPOS:2:22
+MOVE :7:M0,0,-1
+MOVE :7:M1,0,-1
+MOVE :6:M1,1,1
+MOVE :6:M0,1,1
+MOVE :6:M0,0,1
+MOVE :6:M0,0,1
+MOVE :7:M1,1,-1
+MOVE :7:M0,1,-1
+MOVE :7:M0,1,-1
+MOVE :7:M1,1,-1
+MOVE :6:M0,1,1
+MOVE :7:M0,1,-1
+MOVE :6:M1,1,1
+MOVE :6:M1,1,1
+MOVE :6:M0,1,1
+MOVE :6:M0,1,1
+MOVE :7:M0,1,-1
+MOVE :7:M1,1,-1
+MOVE :7:M0,1,-1
+MOVE :7:M1,1,-1
+MOVE :6:M0,1,1
+MOVE :7:M1,0,-1
+MOVE :7:M0,1,-1
+MOVE :6:M1,0,1
+MOVE :6:M1,1,1
+MOVE :6:M1,1,1
diff --git a/apps/plugins/puzzles/icons/undead.sav b/apps/plugins/puzzles/icons/undead.sav
new file mode 100644
index 0000000..3c314dd
--- /dev/null
+++ b/apps/plugins/puzzles/icons/undead.sav
@@ -0,0 +1,14 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :6:Undead
+PARAMS :6:4x4de2
+CPARAMS :6:4x4de2
+DESC :48:5,2,2,aRLgLLaLRL,2,0,1,2,1,1,2,5,0,0,0,2,1,3,1,1
+NSTATES :1:7
+STATEPOS:1:7
+MOVE :2:G0
+MOVE :2:V0
+MOVE :2:G2
+MOVE :2:G3
+MOVE :2:V3
+MOVE :2:Z3
diff --git a/apps/plugins/puzzles/icons/unequal.sav b/apps/plugins/puzzles/icons/unequal.sav
new file mode 100644
index 0000000..c414513
--- /dev/null
+++ b/apps/plugins/puzzles/icons/unequal.sav
@@ -0,0 +1,25 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :7:Unequal
+PARAMS :3:4de
+CPARAMS :3:4de
+SEED :15:143029490219212
+DESC :37:0D,0,0L,0,0,0,0,0,0D,0U,0R,0,0,0,0,4,
+AUXINFO :34:f51274dc41e0a39caa38942fc525ed0108
+NSTATES :2:16
+STATEPOS:1:6
+MOVE :6:R2,1,4
+MOVE :6:R1,2,4
+MOVE :6:R0,0,4
+MOVE :6:R2,3,1
+MOVE :6:R3,2,1
+MOVE :6:R0,2,3
+MOVE :6:R2,2,2
+MOVE :6:R0,3,2
+MOVE :6:R1,3,3
+MOVE :6:R0,1,1
+MOVE :6:R1,1,2
+MOVE :6:R3,1,3
+MOVE :6:R3,0,2
+MOVE :6:R2,0,3
+MOVE :6:R1,0,1
diff --git a/apps/plugins/puzzles/icons/unruly.sav b/apps/plugins/puzzles/icons/unruly.sav
new file mode 100644
index 0000000..0f7ca1b
--- /dev/null
+++ b/apps/plugins/puzzles/icons/unruly.sav
@@ -0,0 +1,22 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :6:Unruly
+PARAMS :5:6x6de
+CPARAMS :5:6x6de
+DESC :10:faCADAJeBd
+NSTATES :2:15
+STATEPOS:2:15
+MOVE :6:P0,1,2
+MOVE :6:P0,4,2
+MOVE :6:P0,3,3
+MOVE :6:P0,3,0
+MOVE :6:P0,5,1
+MOVE :6:P0,2,1
+MOVE :6:P1,4,0
+MOVE :6:P1,1,1
+MOVE :6:P1,5,2
+MOVE :6:P0,0,2
+MOVE :6:P1,0,3
+MOVE :6:P1,0,0
+MOVE :6:P1,0,4
+MOVE :6:P0,2,4
diff --git a/apps/plugins/puzzles/icons/untangle.sav b/apps/plugins/puzzles/icons/untangle.sav
new file mode 100644
index 0000000..016318a
--- /dev/null
+++ b/apps/plugins/puzzles/icons/untangle.sav
@@ -0,0 +1,16 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME :8:Untangle
+PARAMS :2:10
+CPARAMS :2:10
+SEED :15:761628688787632
+DESC :63:0-1,0-5,0-8,0-9,1-4,1-8,2-6,2-7,3-5,3-6,3-9,4-5,4-7,5-7,6-7,8-9
+AUXINFO :182:01bee8258e3164fe966f294b2837b6584b965b8d8e97571ba48f26c9bc0a91ac4b49fb4652bfaa5c340c82c57afbaa4620f2f6d49d7a7b330a66594d2b88c499d57c4093379b7dc322f2afa1ebab81004585751c39c19f8f9930c4
+NSTATES :1:7
+STATEPOS:1:6
+MOVE :12:P8:168,16/64
+MOVE :12:P0:186,85/64
+MOVE :12:P2:47,254/64
+MOVE :13:P5:131,153/64
+MOVE :12:P3:75,126/64
+MOVE :12:P7:93,303/64
diff --git a/apps/plugins/puzzles/icons/win16pal.xpm b/apps/plugins/puzzles/icons/win16pal.xpm
new file mode 100644
index 0000000..66fd60a
--- /dev/null
+++ b/apps/plugins/puzzles/icons/win16pal.xpm
@@ -0,0 +1,23 @@
+/* XPM */
+static char *win16pal[] = {
+/* columns rows colors chars-per-pixel */
+"16 1 16 1",
+" c #000000",
+". c #800000",
+"X c #008000",
+"o c #808000",
+"O c #000080",
+"+ c #800080",
+"@ c #008080",
+"# c #C0C0C0",
+"$ c #808080",
+"% c #FF0000",
+"& c #00FF00",
+"* c #FFFF00",
+"= c #0000FF",
+"- c #FF00FF",
+"; c #00FFFF",
+": c #FFFFFF",
+/* pixels */
+" .XoO+@#$%&*=-;:"
+};