ref: cf880225edb1b6a5cb27dec01ba54c61822788f2
parent: f05c25347d66821d928668a7e87dffbf3ffed027
author: Simon Tatham <anakin@pobox.com>
date: Sat Aug 5 13:20:29 EDT 2006
I'm sick of repeatedly adding and removing local changes to Recipe when testing a new game, so here's a new architecture for the Recipe file. mkfiles.pl now supports several new features: - an `!include' directive, which accepts wildcards - += to append to an existing object group definition - the ability to divert output to an arbitrary file. So now each puzzle has a `.R' file containing a fragment of Recipe code describing that puzzle, and the central Recipe does `!include *.R' to construct the Makefiles. That way, I can keep as many experimental half-finished puzzles lying around my working directory as I like, and I won't have to keep reverting Recipe when I check in any other changes. As part of this change, list.c is no longer a version-controlled file; it's now constructed by mkfiles.pl, so that it too can take advantage of this mechanism. [originally from svn r6781]
--- a/CHECKLST.txt
+++ b/CHECKLST.txt
@@ -6,20 +6,25 @@
Write the source file for the new puzzle (duhh).
-Add it to Recipe in _four_ places:
- - the `ALL' definition, to ensure it is compiled into the OS X binary
- - as a GTK build target
- - as a Windows build target
- - in the Unix `make install' section at the bottom.
+Create a .R file for it which:
+ - defines a Recipe symbol for it if it requires auxiliary object
+ files
+ - adds it to the `ALL' definition, to ensure it is compiled into
+ the OS X binary
+ - adds it as a GTK build target
+ - adds it as a Windows build target
+ - adds auxiliary solver binaries if any
+ - adds it to $(GAMES) in the GTK makefile, for `make install'
+ - adds it to list.c for the OS X binary.
If the puzzle is by a new author, modify the copyright notice in
LICENCE and in puzzles.but. (Also in index.html, but that's listed
below under website changes.)
-Add it to list.c so that the OS X binary will be able to select it
-from the menus. (Also, double-check that the game structure name in
-the source file has been renamed from `nullgame'. Actually compiling
-it on OS X would be a good way to check this, if convenient.)
+Double-check that the game structure name in the source file has
+been renamed from `nullgame', so that it'll work on OS X. Actually
+compiling it on OS X would be a good way to check this, if
+convenient.
Add a documentation section in puzzles.but.
--- a/Recipe
+++ b/Recipe
@@ -16,95 +16,38 @@
WINDOWS = windows printing
+ user32.lib gdi32.lib comctl32.lib comdlg32.lib winspool.lib
COMMON = midend drawing misc malloc random version
-NET = net tree234 dsf
-NETSLIDE = netslide tree234
-MINES = mines tree234
-FLIP = flip tree234
-PEGS = pegs tree234
-UNTANGLE = untangle tree234
-SLANT = slant dsf
-MAP = map dsf
-LOOPY = loopy tree234 dsf
-LIGHTUP = lightup combi
-TENTS = tents maxflow
-BRIDGES = bridges dsf
-
-ALL = list NET NETSLIDE cube fifteen sixteen rect pattern solo twiddle
- + MINES samegame FLIP guess PEGS dominosa UNTANGLE blackbox SLANT
- + LIGHTUP MAP LOOPY inertia TENTS BRIDGES
-
GTK = gtk printing ps
+# Objects needed for auxiliary command-line programs.
+STANDALONE = nullfe random misc malloc
-net : [X] GTK COMMON NET
-netslide : [X] GTK COMMON NETSLIDE
-cube : [X] GTK COMMON cube
-fifteen : [X] GTK COMMON fifteen
-sixteen : [X] GTK COMMON sixteen
-rect : [X] GTK COMMON rect
-pattern : [X] GTK COMMON pattern
-solo : [X] GTK COMMON solo
-twiddle : [X] GTK COMMON twiddle
-mines : [X] GTK COMMON MINES
-samegame : [X] GTK COMMON samegame
-flip : [X] GTK COMMON FLIP
-guess : [X] GTK COMMON guess
-pegs : [X] GTK COMMON PEGS
-dominosa : [X] GTK COMMON dominosa
-untangle : [X] GTK COMMON UNTANGLE
-blackbox : [X] GTK COMMON blackbox
-slant : [X] GTK COMMON SLANT
-lightup : [X] GTK COMMON LIGHTUP
-map : [X] GTK COMMON MAP
-loopy : [X] GTK COMMON LOOPY
-inertia : [X] GTK COMMON inertia
-tents : [X] GTK COMMON TENTS
-bridges : [X] GTK COMMON BRIDGES
+ALL = list
-# Auxiliary command-line programs.
-STANDALONE = nullfe random misc malloc
+# First half of list.c.
+!begin >list.c
+/*
+ * list.c: List of pointers to puzzle structures, for monolithic
+ * platforms.
+ *
+ * This file is automatically generated by mkfiles.pl. Do not edit
+ * it directly, or the changes will be lost next time mkfiles.pl runs.
+ * Instead, edit Recipe and/or its *.R subfiles.
+ */
+#include "puzzles.h"
+#define GAMELIST(A) \
+!end
-solosolver : [U] solo[STANDALONE_SOLVER] STANDALONE
-patternsolver : [U] pattern[STANDALONE_SOLVER] STANDALONE
-mineobfusc : [U] mines[STANDALONE_OBFUSCATOR] tree234 STANDALONE
-slantsolver : [U] slant[STANDALONE_SOLVER] dsf STANDALONE
-mapsolver : [U] map[STANDALONE_SOLVER] dsf STANDALONE m.lib
-lightupsolver : [U] lightup[STANDALONE_SOLVER] combi STANDALONE
-tentssolver : [U] tents[STANDALONE_SOLVER] maxflow STANDALONE
+# Now each .R file adds part of the macro definition of GAMELIST to list.c.
+!include *.R
-solosolver : [C] solo[STANDALONE_SOLVER] STANDALONE
-patternsolver : [C] pattern[STANDALONE_SOLVER] STANDALONE
-mineobfusc : [C] mines[STANDALONE_OBFUSCATOR] tree234 STANDALONE
-slantsolver : [C] slant[STANDALONE_SOLVER] dsf STANDALONE
-mapsolver : [C] map[STANDALONE_SOLVER] dsf STANDALONE
-lightupsolver : [C] lightup[STANDALONE_SOLVER] combi STANDALONE
-tentssolver : [C] tents[STANDALONE_SOLVER] maxflow STANDALONE
+# Then we finish up list.c as follows:
+!begin >list.c
-# The Windows Net shouldn't be called `net.exe' since Windows
-# already has a reasonably important utility program by that name!
-netgame : [G] WINDOWS COMMON NET
-netslide : [G] WINDOWS COMMON NETSLIDE
-cube : [G] WINDOWS COMMON cube
-fifteen : [G] WINDOWS COMMON fifteen
-sixteen : [G] WINDOWS COMMON sixteen
-rect : [G] WINDOWS COMMON rect
-pattern : [G] WINDOWS COMMON pattern
-solo : [G] WINDOWS COMMON solo
-twiddle : [G] WINDOWS COMMON twiddle
-mines : [G] WINDOWS COMMON MINES
-samegame : [G] WINDOWS COMMON samegame
-flip : [G] WINDOWS COMMON FLIP
-guess : [G] WINDOWS COMMON guess
-pegs : [G] WINDOWS COMMON PEGS
-dominosa : [G] WINDOWS COMMON dominosa
-untangle : [G] WINDOWS COMMON UNTANGLE
-blackbox : [G] WINDOWS COMMON blackbox
-slant : [G] WINDOWS COMMON SLANT
-lightup : [G] WINDOWS COMMON LIGHTUP
-map : [G] WINDOWS COMMON MAP
-loopy : [G] WINDOWS COMMON LOOPY
-inertia : [G] WINDOWS COMMON inertia
-tents : [G] WINDOWS COMMON TENTS
-bridges : [G] WINDOWS COMMON BRIDGES
+#define DECL(x) extern const game x;
+#define REF(x) &x,
+GAMELIST(DECL)
+const game *gamelist[] = { GAMELIST(REF) };
+const int gamecount = lenof(gamelist);
+!end
# Mac OS X unified application containing all the puzzles.
Puzzles : [MX] osx osx.icns osx-info.plist COMMON ALL
@@ -138,17 +81,6 @@
rm -f raw.dmg devicename
!end
-# The `nullgame' source file is a largely blank one, which contains
-# all the correct function definitions to compile and link, but
-# which defines the null game in which nothing is ever drawn and
-# there are no valid moves. Its main purpose is to act as a
-# template for writing new game definition source files. I include
-# it in the Makefile because it will be worse than useless if it
-# ever fails to compile, so it's important that it should actually
-# be built on a regular basis.
-nullgame : [X] GTK COMMON nullgame
-nullgame : [G] WINDOWS COMMON nullgame
-
# Version management.
!begin vc
version.obj: *.c *.h
@@ -194,10 +126,7 @@
# make install for Unix.
!begin gtk
install:
- for i in cube net netslide fifteen sixteen twiddle \
- pattern rect solo mines samegame flip guess \
- pegs dominosa untangle blackbox slant lightup \
- map loopy inertia tents bridges; do \
+ for i in $(GAMES); do \
$(INSTALL_PROGRAM) -m 755 $$i $(DESTDIR)$(gamesdir)/$$i \
|| exit 1; \
done
--- /dev/null
+++ b/blackbox.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+blackbox : [X] GTK COMMON blackbox
+
+blackbox : [G] WINDOWS COMMON blackbox
+
+ALL += blackbox
+
+!begin gtk
+GAMES += blackbox
+!end
+
+!begin >list.c
+ A(blackbox) \
+!end
--- /dev/null
+++ b/bridges.R
@@ -1,0 +1,17 @@
+# -*- makefile -*-
+
+BRIDGES = bridges dsf
+
+bridges : [X] GTK COMMON BRIDGES
+
+bridges : [G] WINDOWS COMMON BRIDGES
+
+ALL += BRIDGES
+
+!begin gtk
+GAMES += bridges
+!end
+
+!begin >list.c
+ A(bridges) \
+!end
--- /dev/null
+++ b/cube.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+cube : [X] GTK COMMON cube
+
+cube : [G] WINDOWS COMMON cube
+
+ALL += cube
+
+!begin gtk
+GAMES += cube
+!end
+
+!begin >list.c
+ A(cube) \
+!end
--- a/devel.but
+++ b/devel.but
@@ -193,7 +193,9 @@
\b On platforms such as MacOS X and PalmOS, which build all the
puzzles into a single monolithic binary, the game structure in each
back end must have a different name, and there's a helper module
-\c{list.c} which contains a complete list of those game structures.
+\c{list.c} (constructed automatically by the same Perl script that
+builds the \cw{Makefile}s) which contains a complete list of those
+game structures.
On the latter type of platform, source files may assume that the
preprocessor symbol \c{COMBINED} has been defined. Thus, the usual
@@ -2916,9 +2918,10 @@
\c extern const int gamecount;
\c{gamelist} will be an array of \c{gamecount} game structures,
-declared in the source module \c{list.c}. The application should
-search that array for the game it wants, probably by reaching into
-each game structure and looking at its \c{name} field.
+declared in the automatically constructed source module \c{list.c}.
+The application should search that array for the game it wants,
+probably by reaching into each game structure and looking at its
+\c{name} field.
}
--- /dev/null
+++ b/dominosa.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+dominosa : [X] GTK COMMON dominosa
+
+dominosa : [G] WINDOWS COMMON dominosa
+
+ALL += dominosa
+
+!begin gtk
+GAMES += dominosa
+!end
+
+!begin >list.c
+ A(dominosa) \
+!end
--- /dev/null
+++ b/fifteen.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+fifteen : [X] GTK COMMON fifteen
+
+fifteen : [G] WINDOWS COMMON fifteen
+
+ALL += fifteen
+
+!begin gtk
+GAMES += fifteen
+!end
+
+!begin >list.c
+ A(fifteen) \
+!end
--- /dev/null
+++ b/flip.R
@@ -1,0 +1,17 @@
+# -*- makefile -*-
+
+FLIP = flip tree234
+
+flip : [X] GTK COMMON FLIP
+
+flip : [G] WINDOWS COMMON FLIP
+
+ALL += FLIP
+
+!begin gtk
+GAMES += flip
+!end
+
+!begin >list.c
+ A(flip) \
+!end
--- /dev/null
+++ b/guess.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+guess : [X] GTK COMMON guess
+
+guess : [G] WINDOWS COMMON guess
+
+ALL += guess
+
+!begin gtk
+GAMES += guess
+!end
+
+!begin >list.c
+ A(guess) \
+!end
--- /dev/null
+++ b/inertia.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+inertia : [X] GTK COMMON inertia
+
+inertia : [G] WINDOWS COMMON inertia
+
+ALL += inertia
+
+!begin gtk
+GAMES += inertia
+!end
+
+!begin >list.c
+ A(inertia) \
+!end
--- /dev/null
+++ b/lightup.R
@@ -1,0 +1,20 @@
+# -*- makefile -*-
+
+LIGHTUP = lightup combi
+
+lightup : [X] GTK COMMON LIGHTUP
+
+lightup : [G] WINDOWS COMMON LIGHTUP
+
+lightupsolver : [U] lightup[STANDALONE_SOLVER] combi STANDALONE
+lightupsolver : [C] lightup[STANDALONE_SOLVER] combi STANDALONE
+
+ALL += LIGHTUP
+
+!begin gtk
+GAMES += lightup
+!end
+
+!begin >list.c
+ A(lightup) \
+!end
--- a/list.c
+++ /dev/null
@@ -1,72 +1,0 @@
-/*
- * list.c: List of puzzles.
- */
-
-#include "puzzles.h"
-
-/*
- * The available games can be most easily enumerated by searching
- * for the line in each game source file saying "#define thegame
- * <gamename>". Hence, the following piece of shell/Perl should
- * regenerate this list automatically:
-
-perl -ne '/^#define thegame (\S+)/ and $1 ne "nullgame" and print "extern const game $1;\n"' *.c
-echo -e '\nconst game *gamelist[] = {'
-perl -ne '/^#define thegame (\S+)/ and $1 ne "nullgame" and print " &$1,\n"' *.c
-echo -e '};\n\nconst int gamecount = lenof(gamelist);'
-
- */
-
-extern const game blackbox;
-extern const game bridges;
-extern const game cube;
-extern const game dominosa;
-extern const game fifteen;
-extern const game flip;
-extern const game guess;
-extern const game inertia;
-extern const game lightup;
-extern const game loopy;
-extern const game map;
-extern const game mines;
-extern const game net;
-extern const game netslide;
-extern const game pattern;
-extern const game pegs;
-extern const game rect;
-extern const game samegame;
-extern const game sixteen;
-extern const game slant;
-extern const game solo;
-extern const game tents;
-extern const game twiddle;
-extern const game untangle;
-
-const game *gamelist[] = {
- &blackbox,
- &bridges,
- &cube,
- &dominosa,
- &fifteen,
- &flip,
- &guess,
- &inertia,
- &lightup,
- &loopy,
- &map,
- &mines,
- &net,
- &netslide,
- &pattern,
- &pegs,
- &rect,
- &samegame,
- &sixteen,
- &slant,
- &solo,
- &tents,
- &twiddle,
- &untangle,
-};
-
-const int gamecount = lenof(gamelist);
--- /dev/null
+++ b/loopy.R
@@ -1,0 +1,17 @@
+# -*- makefile -*-
+
+LOOPY = loopy tree234 dsf
+
+loopy : [X] GTK COMMON LOOPY
+
+loopy : [G] WINDOWS COMMON LOOPY
+
+ALL += LOOPY
+
+!begin gtk
+GAMES += loopy
+!end
+
+!begin >list.c
+ A(loopy) \
+!end
--- /dev/null
+++ b/map.R
@@ -1,0 +1,20 @@
+# -*- makefile -*-
+
+MAP = map dsf
+
+map : [X] GTK COMMON MAP
+
+map : [G] WINDOWS COMMON MAP
+
+mapsolver : [U] map[STANDALONE_SOLVER] dsf STANDALONE m.lib
+mapsolver : [C] map[STANDALONE_SOLVER] dsf STANDALONE
+
+ALL += MAP
+
+!begin gtk
+GAMES += map
+!end
+
+!begin >list.c
+ A(map) \
+!end
--- /dev/null
+++ b/mines.R
@@ -1,0 +1,20 @@
+# -*- makefile -*-
+
+MINES = mines tree234
+
+mines : [X] GTK COMMON MINES
+
+mines : [G] WINDOWS COMMON MINES
+
+mineobfusc : [U] mines[STANDALONE_OBFUSCATOR] tree234 STANDALONE
+mineobfusc : [C] mines[STANDALONE_OBFUSCATOR] tree234 STANDALONE
+
+ALL += MINES
+
+!begin gtk
+GAMES += mines
+!end
+
+!begin >list.c
+ A(mines) \
+!end
--- a/mkfiles.pl
+++ b/mkfiles.pl
@@ -17,16 +17,19 @@
# - special-define objects (foo.o[PREPROCSYMBOL]) are not
# supported in the mac or vcproj makefiles.
-use FileHandle;
+use IO::Handle;
use Cwd;
-open IN, "Recipe" or do {
+@filestack = ();
+$in = new IO::Handle;
+open $in, "Recipe" or do {
# We want to deal correctly with being run from one of the
# subdirs in the source tree. So if we can't find Recipe here,
# try one level up.
chdir "..";
- open IN, "Recipe" or die "unable to open Recipe file\n";
+ open $in, "Recipe" or die "unable to open Recipe file\n";
};
+push @filestack, $in;
# HACK: One of the source files in `charset' is auto-generated by
# sbcsgen.pl. We need to generate that _now_, before attempting
@@ -45,13 +48,20 @@
@allobjs = (); # all object file names
-while (<IN>) {
+readinput: while (1) {
+ while (not defined ($_ = <$in>)) {
+ close $in;
+ last readinput if 0 == scalar @filestack;
+ $in = pop @filestack;
+ }
+
+ chomp;
+ split;
+
# Skip comments (unless the comments belong, for example because
# they're part of a diversion).
next if /^\s*#/ and !defined $divert;
- chomp;
- split;
if ($_[0] eq "!begin" and $_[1] eq "help") { $divert = \$help; next; }
if ($_[0] eq "!end") { $divert = undef; next; }
if ($_[0] eq "!name") { $project_name = $_[1]; next; }
@@ -59,13 +69,27 @@
if ($_[0] eq "!makefile" and &mfval($_[1])) { $makefiles{$_[1]}=$_[2]; next;}
if ($_[0] eq "!specialobj" and &mfval($_[1])) { $specialobj{$_[1]}->{$_[2]} = 1; next;}
if ($_[0] eq "!begin") {
- if (&mfval($_[1])) {
+ if ($_[1] =~ /^>(.*)/) {
+ $divert = \$auxfiles{$1};
+ } elsif (&mfval($_[1])) {
$divert = \$makefile_extra{$_[1]};
- } else {
- $divert = \$dummy;
}
next;
}
+ if ($_[0] eq "!include") {
+ @newfiles = ();
+ for ($i = 1; $i <= $#_; $i++) {
+ push @newfiles, (sort glob $_[$i]);
+ }
+ for ($i = $#newfiles; $i >= 0; $i--) {
+ $file = $newfiles[$i];
+ $f = new IO::Handle;
+ open $f, "<$file" or die "unable to open include file '$file'\n";
+ push @filestack, $f;
+ }
+ $in = $filestack[$#filestack];
+ next;
+ }
# If we're gathering help text, keep doing so.
if (defined $divert) { ${$divert} .= "$_\n"; next; }
# Ignore blank lines.
@@ -80,6 +104,11 @@
$prog = undef;
die "$.: unexpected + line\n" if !defined $lastlistref;
} elsif ($_[1] eq "=") {
+ $groups{$_[0]} = [];
+ $listref = $groups{$_[0]};
+ $prog = undef;
+ shift @objs; # eat the group name
+ } elsif ($_[1] eq "+=") {
$groups{$_[0]} = [] if !defined $groups{$_[0]};
$listref = $groups{$_[0]};
$prog = undef;
@@ -89,7 +118,7 @@
$prog = $_[0];
shift @objs; # eat the program name
} else {
- die "$.: unrecognised line type\n";
+ die "$.: unrecognised line type: '$_'\n";
}
shift @objs; # eat the +, the = or the :
@@ -113,7 +142,11 @@
$lastlistref = $listref;
}
-close IN;
+foreach $aux (sort keys %auxfiles) {
+ open AUX, ">$aux";
+ print AUX $auxfiles{$aux};
+ close AUX;
+}
# Find object file names with predefines (in square brackets after
# the module name), and decide on actual object names for them.
--- /dev/null
+++ b/net.R
@@ -1,0 +1,19 @@
+# -*- makefile -*-
+
+NET = net tree234 dsf
+
+net : [X] GTK COMMON NET
+
+# The Windows Net shouldn't be called `net.exe' since Windows
+# already has a reasonably important utility program by that name!
+netgame : [G] WINDOWS COMMON NET
+
+ALL += NET
+
+!begin gtk
+GAMES += net
+!end
+
+!begin >list.c
+ A(net) \
+!end
--- /dev/null
+++ b/netslide.R
@@ -1,0 +1,17 @@
+# -*- makefile -*-
+
+NETSLIDE = netslide tree234
+
+netslide : [X] GTK COMMON NETSLIDE
+
+netslide : [G] WINDOWS COMMON NETSLIDE
+
+ALL += NETSLIDE
+
+!begin gtk
+GAMES += netslide
+!end
+
+!begin >list.c
+ A(netslide) \
+!end
--- /dev/null
+++ b/nullgame.R
@@ -1,0 +1,12 @@
+# -*- makefile -*-
+
+# The `nullgame' source file is a largely blank one, which contains
+# all the correct function definitions to compile and link, but
+# which defines the null game in which nothing is ever drawn and
+# there are no valid moves. Its main purpose is to act as a
+# template for writing new game definition source files. I include
+# it in the Makefile because it will be worse than useless if it
+# ever fails to compile, so it's important that it should actually
+# be built on a regular basis.
+nullgame : [X] GTK COMMON nullgame
+nullgame : [G] WINDOWS COMMON nullgame
--- /dev/null
+++ b/pattern.R
@@ -1,0 +1,18 @@
+# -*- makefile -*-
+
+pattern : [X] GTK COMMON pattern
+
+pattern : [G] WINDOWS COMMON pattern
+
+patternsolver : [U] pattern[STANDALONE_SOLVER] STANDALONE
+patternsolver : [C] pattern[STANDALONE_SOLVER] STANDALONE
+
+ALL += pattern
+
+!begin gtk
+GAMES += pattern
+!end
+
+!begin >list.c
+ A(pattern) \
+!end
--- /dev/null
+++ b/pegs.R
@@ -1,0 +1,17 @@
+# -*- makefile -*-
+
+PEGS = pegs tree234
+
+pegs : [X] GTK COMMON PEGS
+
+pegs : [G] WINDOWS COMMON PEGS
+
+ALL += PEGS
+
+!begin gtk
+GAMES += pegs
+!end
+
+!begin >list.c
+ A(pegs) \
+!end
--- /dev/null
+++ b/rect.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+rect : [X] GTK COMMON rect
+
+rect : [G] WINDOWS COMMON rect
+
+ALL += rect
+
+!begin gtk
+GAMES += rect
+!end
+
+!begin >list.c
+ A(rect) \
+!end
--- /dev/null
+++ b/samegame.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+samegame : [X] GTK COMMON samegame
+
+samegame : [G] WINDOWS COMMON samegame
+
+ALL += samegame
+
+!begin gtk
+GAMES += samegame
+!end
+
+!begin >list.c
+ A(samegame) \
+!end
--- /dev/null
+++ b/sixteen.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+sixteen : [X] GTK COMMON sixteen
+
+sixteen : [G] WINDOWS COMMON sixteen
+
+ALL += sixteen
+
+!begin gtk
+GAMES += sixteen
+!end
+
+!begin >list.c
+ A(sixteen) \
+!end
--- /dev/null
+++ b/slant.R
@@ -1,0 +1,20 @@
+# -*- makefile -*-
+
+SLANT = slant dsf
+
+slant : [X] GTK COMMON SLANT
+
+slant : [G] WINDOWS COMMON SLANT
+
+slantsolver : [U] slant[STANDALONE_SOLVER] dsf STANDALONE
+slantsolver : [C] slant[STANDALONE_SOLVER] dsf STANDALONE
+
+ALL += SLANT
+
+!begin gtk
+GAMES += slant
+!end
+
+!begin >list.c
+ A(slant) \
+!end
--- /dev/null
+++ b/solo.R
@@ -1,0 +1,18 @@
+# -*- makefile -*-
+
+solo : [X] GTK COMMON solo
+
+solo : [G] WINDOWS COMMON solo
+
+solosolver : [U] solo[STANDALONE_SOLVER] STANDALONE
+solosolver : [C] solo[STANDALONE_SOLVER] STANDALONE
+
+ALL += solo
+
+!begin gtk
+GAMES += solo
+!end
+
+!begin >list.c
+ A(solo) \
+!end
--- /dev/null
+++ b/tents.R
@@ -1,0 +1,20 @@
+# -*- makefile -*-
+
+TENTS = tents maxflow
+
+tents : [X] GTK COMMON TENTS
+
+tents : [G] WINDOWS COMMON TENTS
+
+ALL += TENTS
+
+tentssolver : [U] tents[STANDALONE_SOLVER] maxflow STANDALONE
+tentssolver : [C] tents[STANDALONE_SOLVER] maxflow STANDALONE
+
+!begin gtk
+GAMES += tents
+!end
+
+!begin >list.c
+ A(tents) \
+!end
--- /dev/null
+++ b/twiddle.R
@@ -1,0 +1,15 @@
+# -*- makefile -*-
+
+twiddle : [X] GTK COMMON twiddle
+
+twiddle : [G] WINDOWS COMMON twiddle
+
+ALL += twiddle
+
+!begin gtk
+GAMES += twiddle
+!end
+
+!begin >list.c
+ A(twiddle) \
+!end
--- /dev/null
+++ b/untangle.R
@@ -1,0 +1,17 @@
+# -*- makefile -*-
+
+UNTANGLE = untangle tree234
+
+untangle : [X] GTK COMMON UNTANGLE
+
+untangle : [G] WINDOWS COMMON UNTANGLE
+
+ALL += UNTANGLE
+
+!begin gtk
+GAMES += untangle
+!end
+
+!begin >list.c
+ A(untangle) \
+!end