chiark / gitweb /
New mechanism for automatic generation of the puzzle screenshots on
authorSimon Tatham <anakin@pobox.com>
Tue, 26 Dec 2006 16:47:28 +0000 (16:47 +0000)
committerSimon Tatham <anakin@pobox.com>
Tue, 26 Dec 2006 16:47:28 +0000 (16:47 +0000)
the web, which I hope will also end up being extended to generate
both Windows and X icons for each individual puzzle. The mechanism
is: for each puzzle there's a save file in the `icons' subdirectory
showing a game state which I think is a decent illustration of the
puzzle, and then there's a nasty set of scripts which runs each
puzzle binary, loads that save file, grabs a screenshot using xwd,
and munges it into shape.

In order to support this I've added two new options (--redo and
--windowid) to all the GTK puzzles, which I don't expect ever to be
used outside the icons makefile. I've also added two more options
(--load and --id) which force a GTK puzzle to treat its command-line
option as a save file or as a game ID respectively (the previous
behaviour was always to guess, and sometimes it guessed wrong).

[originally from svn r7014]

31 files changed:
CHECKLST.txt
gtk.c
icons/Makefile [new file with mode: 0644]
icons/blackbox.sav [new file with mode: 0644]
icons/bridges.sav [new file with mode: 0644]
icons/cube.sav [new file with mode: 0644]
icons/dominosa.sav [new file with mode: 0644]
icons/fifteen.sav [new file with mode: 0644]
icons/flip.sav [new file with mode: 0644]
icons/guess.sav [new file with mode: 0644]
icons/inertia.sav [new file with mode: 0644]
icons/lightup.sav [new file with mode: 0644]
icons/loopy.sav [new file with mode: 0644]
icons/map.sav [new file with mode: 0644]
icons/mines.sav [new file with mode: 0644]
icons/net.sav [new file with mode: 0644]
icons/netslide.sav [new file with mode: 0644]
icons/pattern.sav [new file with mode: 0644]
icons/pegs.sav [new file with mode: 0644]
icons/rect.sav [new file with mode: 0644]
icons/samegame.sav [new file with mode: 0644]
icons/screenshot.sh [new file with mode: 0755]
icons/sixteen.sav [new file with mode: 0644]
icons/slant.sav [new file with mode: 0644]
icons/solo.sav [new file with mode: 0644]
icons/square.pl [new file with mode: 0755]
icons/tents.sav [new file with mode: 0644]
icons/twiddle.sav [new file with mode: 0644]
icons/untangle.sav [new file with mode: 0644]
midend.c
puzzles.h

index 3396bf3bf540c425486788a987bd969f834410d0..a6291630d4f3f118206c2032a3bd70c403f06e19 100644 (file)
@@ -34,11 +34,16 @@ structure in the source file.
 
 Add the new Unix binary name to the svn:ignore property.
 
-Don't forget to `svn add' the new source file, and the new .R file,
-before checkin!
+Make a screenshot:
+ - create an appropriate save file in `icons'
+ - add the puzzle name to icons/Makefile
+ - set up a REDO property in icons/Makefile if desired
+
+Don't forget to `svn add' the new source file, the new .R file and
+the save file in `icons', before checkin!
 
 Put the puzzle on the web:
- - make a screenshot
+ - make sure the screenshot is actually in the www directory
  - add an entry in the puzzles list in index.html
  - adjust the copyright in index.html if the puzzle is by a new
    author
diff --git a/gtk.c b/gtk.c
index 99cc4cbdb79bf758e0f1192f219e24f7588b1aa6..d9b9a276715421ef410d538aaa023980af4663c4 100644 (file)
--- a/gtk.c
+++ b/gtk.c
@@ -1451,7 +1451,9 @@ static void add_menu_separator(GtkContainer *cont)
     gtk_widget_show(menuitem);
 }
 
-static frontend *new_window(char *arg, char **error)
+enum { ARG_EITHER, ARG_SAVE, ARG_ID }; /* for argtype */
+
+static frontend *new_window(char *arg, int argtype, char **error)
 {
     frontend *fe;
     GtkBox *vbox;
@@ -1468,30 +1470,53 @@ static frontend *new_window(char *arg, char **error)
 
     if (arg) {
        char *err;
+       FILE *fp;
 
        errbuf[0] = '\0';
 
-       /*
-        * Try treating the argument as a game ID.
-        */
-        err = midend_game_id(fe->me, arg);
-        if (!err) {
-           /*
-            * It's a valid game ID.
-            */
-           midend_new_game(fe->me);
-       } else {
-           FILE *fp = fopen(arg, "r");
+       switch (argtype) {
+         case ARG_ID:
+           err = midend_game_id(fe->me, arg);
+           if (!err)
+               midend_new_game(fe->me);
+           else
+               sprintf(errbuf, "Invalid game ID: %.800s", err);
+           break;
+         case ARG_SAVE:
+           fp = fopen(arg, "r");
            if (!fp) {
-               sprintf(errbuf, "Supplied argument is neither a game ID (%.400s)"
-                       " nor a save file (%.400s)", err, strerror(errno));
+               sprintf(errbuf, "Error opening file: %.800s", strerror(errno));
            } else {
                err = midend_deserialise(fe->me, savefile_read, fp);
                 if (err)
-                    sprintf(errbuf, "%.800s", err);
+                    sprintf(errbuf, "Invalid save file: %.800s", err);
                 fclose(fp);
            }
-        }
+           break;
+         default /*case ARG_EITHER*/:
+           /*
+            * First try treating the argument as a game ID.
+            */
+           err = midend_game_id(fe->me, arg);
+           if (!err) {
+               /*
+                * It's a valid game ID.
+                */
+               midend_new_game(fe->me);
+           } else {
+               FILE *fp = fopen(arg, "r");
+               if (!fp) {
+                   sprintf(errbuf, "Supplied argument is neither a game ID (%.400s)"
+                           " nor a save file (%.400s)", err, strerror(errno));
+               } else {
+                   err = midend_deserialise(fe->me, savefile_read, fp);
+                   if (err)
+                       sprintf(errbuf, "%.800s", err);
+                   fclose(fp);
+               }
+           }
+           break;
+       }
        if (*errbuf) {
            *error = dupstr(errbuf);
            midend_free(fe->me);
@@ -1755,7 +1780,10 @@ int main(int argc, char **argv)
     int ngenerate = 0, print = FALSE, px = 1, py = 1;
     int soln = FALSE, colour = FALSE;
     float scale = 1.0F;
+    float redo_proportion = 0.0F;
     char *arg = NULL;
+    int argtype = ARG_EITHER;
+    int output_window_id = FALSE;
     int doing_opts = TRUE;
     int ac = argc;
     char **av = argv;
@@ -1826,6 +1854,42 @@ int main(int argc, char **argv)
                        pname);
                return 1;
            }
+       } else if (doing_opts && !strcmp(p, "--redo")) {
+           /*
+            * This is an internal option which I don't expect
+            * users to have any particular use for. The effect of
+            * --redo is that once the game has been loaded and
+            * initialised, the next move in the redo chain is
+            * replayed, and the game screen is redrawn part way
+            * through the making of the move. This is only
+            * meaningful if there _is_ a next move in the redo
+            * chain, which means in turn that this option is only
+            * useful if you're also passing a save file on the
+            * command line.
+            *
+            * This option is used by the script which generates
+            * the puzzle icons and website screenshots, and I
+            * don't imagine it's useful for anything else.
+            * (Unless, I suppose, users don't like my screenshots
+            * and want to generate their own in the same way for
+            * some repackaged version of the puzzles.)
+            */
+           if (--ac > 0) {
+               redo_proportion = atof(*++av);
+           } else {
+               fprintf(stderr, "%s: no argument supplied to '--redo'\n",
+                       pname);
+               return 1;
+           }
+       } else if (doing_opts && !strcmp(p, "--windowid")) {
+           /*
+            * Another internal option for the icon building
+            * script. This causes the window ID of the central
+            * drawing area (i.e. not including the menu bar or
+            * status bar) to be printed on standard output once
+            * the window has been drawn.
+            */
+           output_window_id = TRUE;
        } else if (doing_opts && (!strcmp(p, "--with-solutions") ||
                                  !strcmp(p, "--with-solution") ||
                                  !strcmp(p, "--with-solns") ||
@@ -1842,6 +1906,10 @@ int main(int argc, char **argv)
                return 1;
            }
            colour = TRUE;
+       } else if (doing_opts && !strcmp(p, "--load")) {
+           argtype = ARG_SAVE;
+       } else if (doing_opts && !strcmp(p, "--game")) {
+           argtype = ARG_ID;
        } else if (doing_opts && !strcmp(p, "--")) {
            doing_opts = FALSE;
        } else if (!doing_opts || p[0] != '-') {
@@ -1971,14 +2039,40 @@ int main(int argc, char **argv)
 
        return 0;
     } else {
+       frontend *fe;
 
        gtk_init(&argc, &argv);
 
-       if (!new_window(argc > 1 ? argv[1] : NULL, &error)) {
+       fe = new_window(arg, argtype, &error);
+
+       if (!fe) {
            fprintf(stderr, "%s: %s\n", pname, error);
            return 1;
        }
 
+       if (output_window_id) {
+           /*
+            * Some puzzles will not redraw their entire area if
+            * given a partially completed animation, which means
+            * we must redraw now and _then_ redraw again after
+            * freezing the move timer.
+            */
+           midend_force_redraw(fe->me);
+       }
+
+       if (redo_proportion) {
+           /* Start a redo. */
+           midend_process_key(fe->me, 0, 0, 'r');
+           /* And freeze the timer at the specified position. */
+           midend_freeze_timer(fe->me, redo_proportion);
+       }
+
+       if (output_window_id) {
+           midend_redraw(fe->me);
+           printf("%p\n", (void *)GDK_WINDOW_XWINDOW(fe->area->window));
+           fflush(stdout);
+       }
+
        gtk_main();
     }
 
diff --git a/icons/Makefile b/icons/Makefile
new file mode 100644 (file)
index 0000000..114de63
--- /dev/null
@@ -0,0 +1,29 @@
+# Makefile for Puzzles icons.
+
+PUZZLES = blackbox bridges cube dominosa fifteen flip guess inertia lightup \
+          loopy map mines net netslide pattern pegs rect samegame sixteen \
+          slant solo tents twiddle untangle
+
+BASEPNGS = $(patsubst %,%-base.png,$(PUZZLES))
+WEBPNGS = $(patsubst %,%-web.png,$(PUZZLES))
+
+BIN = ../
+PIC = ./
+
+base: $(BASEPNGS)
+webpics: $(WEBPNGS)
+
+fifteen.png : override REDO=0.3
+flip.png : override REDO=0.3
+netslide.png : override REDO=0.3
+sixteen.png : override REDO=0.3
+twiddle.png : override REDO=0.3
+
+$(BASEPNGS): %-base.png: $(BIN)% $(PIC)%.sav $(PIC)screenshot.sh
+       $(PIC)screenshot.sh $(BIN)$* $(PIC)$*.sav $@ $(REDO)
+
+$(WEBPNGS): %-web.png: %-base.png
+       $(PIC)square.pl 150 5 $^ $@
+
+clean:
+       rm -f *.png
diff --git a/icons/blackbox.sav b/icons/blackbox.sav
new file mode 100644 (file)
index 0000000..4483f3c
--- /dev/null
@@ -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/icons/bridges.sav b/icons/bridges.sav
new file mode 100644 (file)
index 0000000..ddae708
--- /dev/null
@@ -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/icons/cube.sav b/icons/cube.sav
new file mode 100644 (file)
index 0000000..bb123f4
--- /dev/null
@@ -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/icons/dominosa.sav b/icons/dominosa.sav
new file mode 100644 (file)
index 0000000..5991f3e
--- /dev/null
@@ -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/icons/fifteen.sav b/icons/fifteen.sav
new file mode 100644 (file)
index 0000000..d81345a
--- /dev/null
@@ -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/icons/flip.sav b/icons/flip.sav
new file mode 100644 (file)
index 0000000..82b4c49
--- /dev/null
@@ -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/icons/guess.sav b/icons/guess.sav
new file mode 100644 (file)
index 0000000..69852bf
--- /dev/null
@@ -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/icons/inertia.sav b/icons/inertia.sav
new file mode 100644 (file)
index 0000000..a6d6fae
--- /dev/null
@@ -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/icons/lightup.sav b/icons/lightup.sav
new file mode 100644 (file)
index 0000000..21b59bd
--- /dev/null
@@ -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/icons/loopy.sav b/icons/loopy.sav
new file mode 100644 (file)
index 0000000..0136d51
--- /dev/null
@@ -0,0 +1,121 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME    :5:Loopy
+PARAMS  :7:7x7r0dh
+CPARAMS :7:7x7r0dh
+SEED    :15:206083918429411
+DESC    :31:02g222b3b2e2a2b322b2a2a3a2a1d1b
+NSTATES :3:113
+STATEPOS:2:75
+MOVE    :5:0,0vn
+MOVE    :5:0,0hn
+MOVE    :5:1,0vn
+MOVE    :5:0,1hn
+MOVE    :5:1,0hn
+MOVE    :5:1,1hy
+MOVE    :5:2,0vy
+MOVE    :5:2,1vn
+MOVE    :5:2,1hn
+MOVE    :5:2,2hy
+MOVE    :5:3,1vy
+MOVE    :5:3,2vn
+MOVE    :5:3,2hn
+MOVE    :5:3,3hy
+MOVE    :5:4,2vy
+MOVE    :5:4,3vn
+MOVE    :5:4,3hn
+MOVE    :5:4,4hy
+MOVE    :5:5,3vy
+MOVE    :5:5,4vn
+MOVE    :5:5,4hn
+MOVE    :5:5,5hy
+MOVE    :5:6,4vy
+MOVE    :5:6,5vn
+MOVE    :5:6,5hn
+MOVE    :5:7,6vy
+MOVE    :5:6,7hy
+MOVE    :5:0,6vy
+MOVE    :5:0,7hy
+MOVE    :5:0,1vn
+MOVE    :5:0,2vy
+MOVE    :5:0,2hy
+MOVE    :5:1,1vy
+MOVE    :5:1,2hn
+MOVE    :5:1,2vn
+MOVE    :5:0,3hy
+MOVE    :5:0,3vn
+MOVE    :5:0,4vy
+MOVE    :5:0,4hy
+MOVE    :5:2,2vy
+MOVE    :5:2,0hy
+MOVE    :5:3,5vy
+MOVE    :5:2,6hy
+MOVE    :5:3,6vn
+MOVE    :5:3,6hn
+MOVE    :5:1,3vn
+MOVE    :5:1,3hy
+MOVE    :5:2,3vn
+MOVE    :5:3,0vn
+MOVE    :5:3,0hy
+MOVE    :5:3,1hy
+MOVE    :5:4,1vn
+MOVE    :5:4,2hy
+MOVE    :5:4,0vn
+MOVE    :5:4,0hy
+MOVE    :5:4,1hy
+MOVE    :5:5,0vn
+MOVE    :5:5,0hy
+MOVE    :5:5,1vn
+MOVE    :5:5,1hy
+MOVE    :5:6,0vn
+MOVE    :5:6,0hy
+MOVE    :5:7,0vy
+MOVE    :5:6,1hn
+MOVE    :5:6,1vy
+MOVE    :5:7,1vy
+MOVE    :5:6,2hn
+MOVE    :5:7,2vy
+MOVE    :5:2,3hn
+MOVE    :5:3,3vy
+MOVE    :5:2,4hy
+MOVE    :5:3,4vn
+MOVE    :5:3,4hn
+MOVE    :5:4,4vy
+MOVE    :5:4,6vy
+MOVE    :5:4,6hn
+MOVE    :5:5,6vn
+MOVE    :5:4,7hn
+MOVE    :5:4,5vy
+MOVE    :5:4,5hn
+MOVE    :5:3,5hn
+MOVE    :5:2,5hy
+MOVE    :5:2,5vn
+MOVE    :5:2,4vn
+MOVE    :5:1,4hy
+MOVE    :5:1,4vn
+MOVE    :5:1,5hy
+MOVE    :5:0,5hy
+MOVE    :5:0,5vn
+MOVE    :5:1,5vn
+MOVE    :5:0,6hy
+MOVE    :5:1,6vn
+MOVE    :5:1,6hy
+MOVE    :5:1,7hy
+MOVE    :5:2,6vn
+MOVE    :5:2,7hy
+MOVE    :5:3,7hy
+MOVE    :5:5,7hn
+MOVE    :5:6,6vy
+MOVE    :5:6,6hn
+MOVE    :5:7,5vy
+MOVE    :5:7,4vy
+MOVE    :5:5,6hy
+MOVE    :5:5,5vy
+MOVE    :5:6,4hn
+MOVE    :5:7,3vy
+MOVE    :5:6,3vy
+MOVE    :5:6,3hn
+MOVE    :5:5,2vn
+MOVE    :5:5,2hy
+MOVE    :5:6,2vn
+MOVE    :5:5,3hy
diff --git a/icons/map.sav b/icons/map.sav
new file mode 100644 (file)
index 0000000..33863e1
--- /dev/null
@@ -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/icons/mines.sav b/icons/mines.sav
new file mode 100644 (file)
index 0000000..a827541
--- /dev/null
@@ -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/icons/net.sav b/icons/net.sav
new file mode 100644 (file)
index 0000000..06a5426
--- /dev/null
@@ -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/icons/netslide.sav b/icons/netslide.sav
new file mode 100644 (file)
index 0000000..f37178e
--- /dev/null
@@ -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/icons/pattern.sav b/icons/pattern.sav
new file mode 100644 (file)
index 0000000..1e6f45f
--- /dev/null
@@ -0,0 +1,30 @@
+SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
+VERSION :1:1
+GAME    :7:Pattern
+PARAMS  :5:10x10
+CPARAMS :5:10x10
+DESC    :67:4.3/2.2/1.4/3.2/2.3.2/4/6/6/3.1/1/1.1.4/1.1.3/3.3/2.3/6/5/4/1.1/5/5
+NSTATES :2:23
+STATEPOS:2:23
+MOVE    :8:F6,4,1,2
+MOVE    :8:F7,4,1,2
+MOVE    :8:F4,4,2,1
+MOVE    :8:E0,4,2,1
+MOVE    :8:F0,0,1,4
+MOVE    :8:F5,5,1,1
+MOVE    :8:E0,5,3,1
+MOVE    :8:F2,6,1,4
+MOVE    :8:E1,7,1,1
+MOVE    :8:E3,7,1,1
+MOVE    :8:F3,6,1,1
+MOVE    :8:E6,6,4,1
+MOVE    :8:F6,0,1,4
+MOVE    :8:F7,0,1,5
+MOVE    :8:E6,6,1,3
+MOVE    :8:E7,7,1,3
+MOVE    :8:E6,9,1,1
+MOVE    :8:F0,7,1,2
+MOVE    :8:F1,8,4,1
+MOVE    :8:E5,8,1,1
+MOVE    :8:F3,9,1,1
+MOVE    :8:F4,9,1,1
diff --git a/icons/pegs.sav b/icons/pegs.sav
new file mode 100644 (file)
index 0000000..22b8a0d
--- /dev/null
@@ -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/icons/rect.sav b/icons/rect.sav
new file mode 100644 (file)
index 0000000..17264da
--- /dev/null
@@ -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/icons/samegame.sav b/icons/samegame.sav
new file mode 100644 (file)
index 0000000..f92b52d
--- /dev/null
@@ -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/icons/screenshot.sh b/icons/screenshot.sh
new file mode 100755 (executable)
index 0000000..cb856be
--- /dev/null
@@ -0,0 +1,34 @@
+#!/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 --windowid --load "$save" 2>/dev/null | {
+  read windowid
+  # I'm not sure why I have to do this sleep, since gtk.c does
+  # carefully redraw the window _before_ outputting the window ID,
+  # but nonetheless this script doesn't seem to be reliable without
+  # it :-/
+  sleep 1
+  xwd -silent -id $windowid | convert xwd:- "$image"
+  xkill -id $windowid >/dev/null
+}
diff --git a/icons/sixteen.sav b/icons/sixteen.sav
new file mode 100644 (file)
index 0000000..076b1fb
--- /dev/null
@@ -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/icons/slant.sav b/icons/slant.sav
new file mode 100644 (file)
index 0000000..02017e5
--- /dev/null
@@ -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/icons/solo.sav b/icons/solo.sav
new file mode 100644 (file)
index 0000000..385cc68
--- /dev/null
@@ -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/icons/square.pl b/icons/square.pl
new file mode 100755 (executable)
index 0000000..295b2f1
--- /dev/null
@@ -0,0 +1,86 @@
+#!/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 $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 $img\n"
+  unless $al == $xl;
+
+# Find the background colour. We assume the image already has a
+# border, so this is just the pixel colour of the top left corner.
+$back = $data->[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/icons/tents.sav b/icons/tents.sav
new file mode 100644 (file)
index 0000000..292c2d2
--- /dev/null
@@ -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/icons/twiddle.sav b/icons/twiddle.sav
new file mode 100644 (file)
index 0000000..2863033
--- /dev/null
@@ -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/icons/untangle.sav b/icons/untangle.sav
new file mode 100644 (file)
index 0000000..016318a
--- /dev/null
@@ -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
index 4d729e354af6a35ab053e79019a3371d9f277157..779ca0c811a3e48fc450e680e27fa301a39aa059 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -740,6 +740,17 @@ void midend_redraw(midend *me)
     }
 }
 
+/*
+ * Nasty hacky function used to implement the --redo option in
+ * gtk.c. Only used for generating the puzzles' icons.
+ */
+void midend_freeze_timer(midend *me, float tprop)
+{
+    me->anim_pos = me->anim_time * tprop;
+    midend_redraw(me);
+    deactivate_timer(me->frontend);
+}
+
 void midend_timer(midend *me, float tplus)
 {
     int need_redraw = (me->anim_time > 0 || me->flash_time > 0);
index 49c2a07b1bb5679407d05bfd9c7b7cc0d061bbfa..129ddd1919c8c06bb55288a662492e75c76fb6a9 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -215,6 +215,7 @@ int midend_process_key(midend *me, int x, int y, int button);
 void midend_force_redraw(midend *me);
 void midend_redraw(midend *me);
 float *midend_colours(midend *me, int *ncolours);
+void midend_freeze_timer(midend *me, float tprop);
 void midend_timer(midend *me, float tplus);
 int midend_num_presets(midend *me);
 void midend_fetch_preset(midend *me, int n,