Migrate to a CMake-based build system.

This completely removes the old system of mkfiles.pl + Recipe + .R
files that I used to manage the various per-platform makefiles and
other build scripts in this code base. In its place is a
CMakeLists.txt setup, which is still able to compile for Linux,
Windows, MacOS, NestedVM and Emscripten.

The main reason for doing this is because mkfiles.pl was a horrible
pile of unmaintainable cruft. It was hard to keep up to date (e.g.
didn't reliably support the latest Visual Studio project files); it
was so specific to me that nobody else could maintain it (or was even
interested in trying, and who can blame them?), and it wasn't even
easy to _use_ if you weren't me. And it didn't even produce very good
makefiles.

In fact I've been wanting to hurl mkfiles.pl in the bin for years, but
was blocked by CMake not quite being able to support my clang-cl based
system for cross-compiling for Windows on Linux. But CMake 3.20 was
released this month and fixes the last bug in that area (it had to do
with preprocessing of .rc files), so now I'm unblocked!

CMake is not perfect, but it's better at mkfiles.pl's job than
mkfiles.pl was, and it has the great advantage that lots of other
people already know about it.

Other advantages of the CMake system:

 - Easier to build with. At least for the big three platforms, it's
   possible to write down a list of build commands that's actually the
   same everywhere ("cmake ." followed by "cmake --build ."). There's
   endless scope for making your end-user cmake commands more fancy
   than that, for various advantages, but very few people _have_ to.

 - Less effort required to add a new puzzle. You just add a puzzle()
   statement to the top-level CMakeLists.txt, instead of needing to
   remember eight separate fiddly things to put in the .R file. (Look
   at the reduction in CHECKLST.txt!)

 - The 'unfinished' subdirectory is now _built_ unconditionally, even
   if the things in it don't go into the 'make install' target. So
   they won't bit-rot in future.

 - Unix build: unified the old icons makefile with the main build, so
   that each puzzle builds without an icon, runs to build its icon,
   then relinks with it.

 - Windows build: far easier to switch back and forth between debug
   and release than with the old makefiles.

 - MacOS build: CMake has its own .dmg generator, which is surely
   better thought out than my ten-line bodge.

 - net reduction in the number of lines of code in the code base. In
   fact, that's still true _even_ if you don't count the deletion of
   mkfiles.pl itself - that script didn't even have the virtue of
   allowing everything else to be done exceptionally concisely.
This commit is contained in:
Simon Tatham
2021-03-29 18:23:11 +01:00
parent 72b28b5e71
commit cc7f5503dc
82 changed files with 1202 additions and 3668 deletions

1
.gitignore vendored
View File

@ -93,7 +93,6 @@
/*.dmg /*.dmg
/*.res /*.res
/*.inf /*.inf
/list.c
/gamedesc.txt /gamedesc.txt
/build.log /build.log
/build.out /build.out

180
Buildscr
View File

@ -9,11 +9,7 @@ module puzzles
set Version $(!builddate).$(vcsid) set Version $(!builddate).$(vcsid)
# Start by substituting the right version number in configure.ac. # Put the version number into the documentation as a versionid.
in puzzles do perl -i~ -pe 's/6.66/$(Version)/' configure.ac
in puzzles do rm configure.ac~
# And put it into the documentation as a versionid.
# use perl to avoid inconsistent behaviour of echo '\v' # use perl to avoid inconsistent behaviour of echo '\v'
in puzzles do perl -e 'print "\n\\versionid Simon Tatham'\''s Portable Puzzle Collection, version $$ARGV[0]\n"' $(Version) >> puzzles.but in puzzles do perl -e 'print "\n\\versionid Simon Tatham'\''s Portable Puzzle Collection, version $$ARGV[0]\n"' $(Version) >> puzzles.but
in puzzles do perl -e 'print "\n\\versionid Simon Tatham'\''s Portable Puzzle Collection, version $$ARGV[0]\n"' $(Version) >> devel.but in puzzles do perl -e 'print "\n\\versionid Simon Tatham'\''s Portable Puzzle Collection, version $$ARGV[0]\n"' $(Version) >> devel.but
@ -26,36 +22,35 @@ in puzzles do echo '$#define VER "Version $(Version)"' >> version.h
# icky in principle because it presumes that my version numbers don't # icky in principle because it presumes that my version numbers don't
# need XML escaping, but frankly, if they ever do then I should fix # need XML escaping, but frankly, if they ever do then I should fix
# them!) # them!)
in puzzles do perl -i -pe 's/Unidentified build/$(Version)/' osx-info.plist in puzzles do perl -i -pe 's/Unidentified build/$(Version)/' osx/Info.plist
# The very first thing we do is to make the source archive, before we
# fill up the build directory with extra files.
delegate -
# Build Windows Help and text versions of the manual for convenience.
in puzzles do halibut --winhelp=puzzles.hlp --text=puzzles.txt puzzles.but
# Build a text version of the HACKING document.
in puzzles do halibut --text=HACKING devel.but
# Get rid of some cruft that isn't really useful in a source tarball.
in puzzles do rm -f Buildscr CHECKLST.txt .gitignore webpage.pl
in . do ln -s puzzles puzzles-$(Version)
in . do tar -chzf puzzles-$(Version).tar.gz puzzles-$(Version)
return puzzles-$(Version).tar.gz
enddelegate
ifneq "$(NOICONS)" yes then ifneq "$(NOICONS)" yes then
# First build some local binaries, to run the icon build. # Run enough of a native Unix build to produce the icons needed for
in puzzles do perl mkfiles.pl -U CFLAGS='-Wwrite-strings -Werror' # the Windows builds and the website.
in puzzles do make -j$(nproc) in puzzles do cmake -B build-icons .
in puzzles/build-icons do make -j$(nproc) icons VERBOSE=1
# Now build the screenshots and icons.
in puzzles/icons do make web winicons gtkicons -j$(nproc)
# Destroy the local binaries and autoconf detritus, mostly to avoid
# wasting network bandwidth by transferring them to the delegate
# servers.
in puzzles do make distclean
endif endif
# Re-run mkfiles.pl now that it knows the icons are there. (Or for the
# first time, if we didn't bother building the icons.)
in puzzles do perl mkfiles.pl
# Rebuild the configure script.
in puzzles do ./mkauto.sh
ifneq "$(NOMACOS)" yes then ifneq "$(NOMACOS)" yes then
# Build the OS X .dmg archive. # Build the OS X binaries and .dmg archive.
delegate osx delegate osx
in puzzles do make -f Makefile.osx clean in puzzles do cmake -B build-osx -DCMAKE_BUILD_TYPE=Release .
in puzzles do make -f Makefile.osx release VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror' -j$(nproc) in puzzles/build-osx do make -j$(nproc) package VERBOSE=1
return puzzles/Puzzles.dmg return puzzles/build-osx/Puzzles.dmg
enddelegate enddelegate
endif endif
@ -63,71 +58,28 @@ ifneq "$(NOWINDOWS)" yes then
# Build the Windows binaries and installer, and the CHM file. # Build the Windows binaries and installer, and the CHM file.
in puzzles do make -f Makefile.doc clean in puzzles do make -f Makefile.doc clean
in puzzles do make -f Makefile.doc -j$(nproc) # build help files for installer in puzzles do make -f Makefile.doc -j$(nproc) # build help files for installer
in puzzles do mason.pl --args '{"version":"$(Version)","descfile":"gamedesc.txt"}' winwix.mc > puzzles.wxs
in puzzles do perl winiss.pl $(Version) gamedesc.txt > puzzles.iss in puzzles do cmake -B build-win64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_TOOLCHAIN_FILE=$(cmake_toolchain_clangcl64) .
ifneq "$(VISUAL_STUDIO)" "yes" then in puzzles do cmake -B build-win32 -DCMAKE_BUILD_TYPE=Release -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded -DCMAKE_TOOLCHAIN_FILE=$(cmake_toolchain_clangcl32) .
in puzzles with clangcl64 do mkdir win64 && Platform=x64 make -f Makefile.clangcl BUILDDIR=win64/ VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror' -j$(nproc) in puzzles/build-win64 do make -j$(nproc) VERBOSE=1
in puzzles with clangcl32 do mkdir win32 && Platform=x86 make -f Makefile.clangcl BUILDDIR=win32/ SUBSYSVER=,5.01 VER=-DVER=$(Version) XFLAGS='-Wwrite-strings -Werror' -j$(nproc) in puzzles/build-win32 do make -j$(nproc) VERBOSE=1
# Code-sign the binaries, if the local bob config provides a script
# to do so. We assume here that the script accepts an -i option to in puzzles do mason.pl --args '{"version":"$(Version)","descfile":"build-win64/gamedesc.txt"}' winwix.mc > puzzles.wxs
# provide a 'more info' URL, and an optional -n option to provide a
# program name, and that it can take multiple .exe filename # Code-sign the binaries, if the local bob config provides a script
# arguments and sign them all in place. # to do so. We assume here that the script accepts an -i option to
ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ win64/*.exe win32/*.exe # provide a 'more info' URL, and an optional -n option to provide a
# Build installers. # program name, and that it can take multiple .exe filename
in puzzles with wixonlinux do candle -arch x64 puzzles.wxs -dWin64=yes -dBindir=win64/ && light -ext WixUIExtension -sval puzzles.wixobj # arguments and sign them all in place.
in puzzles with wixonlinux do candle -arch x86 puzzles.wxs -dWin64=no -dBindir=win32/ && light -ext WixUIExtension -sval puzzles.wixobj -o puzzles32.msi ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ build-win64/*.exe build-win32/*.exe
ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ -n "Simon Tatham's Portable Puzzle Collection Installer" puzzles.msi puzzles32.msi # Build installers.
else in puzzles with wixonlinux do candle -arch x64 puzzles.wxs -dWin64=yes -dBindir=build-win64/ && light -ext WixUIExtension -sval puzzles.wixobj
delegate windows in puzzles with wixonlinux do candle -arch x86 puzzles.wxs -dWin64=no -dBindir=build-win32/ && light -ext WixUIExtension -sval puzzles.wixobj -o puzzles32.msi
in puzzles with visualstudio do/win nmake -f Makefile.vc clean ifneq "$(cross_winsigncode)" "" in puzzles do $(cross_winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ -n "Simon Tatham's Portable Puzzle Collection Installer" puzzles.msi puzzles32.msi
in puzzles with visualstudio do/win nmake -f Makefile.vc VER=-DVER=$(Version)
ifneq "$(winsigncode)" "" in puzzles do $(winsigncode) -i https://www.chiark.greenend.org.uk/~sgtatham/puzzles/ win64/*.exe in puzzles do chmod +x build-win32/*.exe build-win64/*.exe
# Build installers.
in puzzles with wix do/win candle puzzles.wxs -dWin64=yes -dBindir=win64/ && light -ext WixUIExtension -sval puzzles.wixobj
in puzzles with innosetup do/win iscc puzzles.iss
return puzzles/win64/*.exe
return puzzles/puzzles.msi
enddelegate
endif
in puzzles do chmod +x win32/*.exe win64/*.exe
endif endif
# Build the Pocket PC binaries and CAB.
#
# NOTE: This part of the build script requires the Windows delegate
# server to have the cabwiz program on its PATH. This will
# typically be at
#
# C:\Program Files\Windows CE Tools\WCE420\POCKET PC 2003\Tools
#
# but it might not be if you've installed it somewhere else, or
# have a different version.
#
# NOTE ALSO: This part of the build is commented out, for the
# moment, because cabwiz does unhelpful things when run from within
# a bob delegate process (or, more generally, when run from any
# terminal-based remote login to a Windows machine, including
# Cygwin opensshd and Windows Telnet). The symptom is that cabwiz
# just beeps and sits there. Until I figure out how to build the
# .cab from an automated process (and I'm willing to consider silly
# approaches such as a third-party CAB generator), I don't think I
# can sensibly enable this build.
#in puzzles do perl wceinf.pl gamedesc.txt > puzzles.inf
#delegate windows
# in puzzles do cmd /c 'wcearmv4 & nmake -f Makefile.wce clean'
# in puzzles do cmd /c 'wcearmv4 & nmake -f Makefile.wce VER=-DVER=$(Version)'
# # Nasty piece of sh here which saves the return code from cabwiz,
# # outputs its errors and/or warnings, and then propagates the
# # return code back to bob. If only cabwiz could output to
# # standard error LIKE EVERY OTHER COMMAND-LINE UTILITY IN THE
# # WORLD, I wouldn't have to do this.
# in puzzles do cat puzzles.inf
# in puzzles do cmd /c 'wcearmv4 & bash -c cabwiz puzzles.inf /err cabwiz.err /cpu ARMV4'; a=$$?; cat cabwiz.err; exit $$a
# return puzzles/puzzles.armv4.cab
#enddelegate
# Build the HTML docs. # Build the HTML docs.
in puzzles do mkdir doc in puzzles do mkdir doc
in puzzles do mkdir devel in puzzles do mkdir devel
@ -136,34 +88,34 @@ in puzzles/devel do halibut --html -Chtml-contents-filename:index.html -Chtml-in
ifneq "$(NOWINDOWS)" yes then ifneq "$(NOWINDOWS)" yes then
# Move the deliver-worthy Windows binaries (those specified in # Move the deliver-worthy Windows binaries (those specified in
# gamedesc.txt, which is generated by mkfiles.pl and helpfully # gamedesc.txt, which is generated by CMakeLists.txt and helpfully
# excludes the command-line auxiliary utilities such as solosolver, # excludes the command-line auxiliary utilities such as solosolver,
# and nullgame.exe) into a subdirectory for easy access. # and nullgame.exe) into a subdirectory for easy access.
in puzzles do mkdir winbin64 winbin32 in puzzles do mkdir winbin64 winbin32
in puzzles/win64 do mv `cut -f2 -d: ../gamedesc.txt` ../winbin64 in puzzles/build-win64 do mv `cut -f2 -d: gamedesc.txt` ../winbin64
in puzzles/win32 do mv `cut -f2 -d: ../gamedesc.txt` ../winbin32 in puzzles/build-win32 do mv `cut -f2 -d: gamedesc.txt` ../winbin32
# Make a zip file of the Windows binaries and help files. # Make a zip file of the Windows binaries and help files.
in puzzles do zip -j puzzles.zip winbin64/*.exe puzzles.chm puzzles.hlp puzzles.cnt in puzzles do zip -j puzzles.zip winbin64/*.exe puzzles.chm puzzles.hlp puzzles.cnt
in puzzles do zip -j puzzles32.zip winbin32/*.exe puzzles.chm puzzles.hlp puzzles.cnt in puzzles do zip -j puzzles32.zip winbin32/*.exe puzzles.chm puzzles.hlp puzzles.cnt
endif endif
# Create the source archive. (That writes the archive into the
# _parent_ directory, so be careful when we deliver it.)
in puzzles do ./makedist.sh $(Version)
# Build the autogenerated pieces of the main web page. # Build the autogenerated pieces of the main web page.
in puzzles do perl webpage.pl in puzzles do cmake -B build-gamedesc . -DCMAKE_TOOLCHAIN_FILE=../cmake/windows-dummy-toolchain.cmake
in puzzles do perl webpage.pl build-gamedesc/gamedesc.txt
ifneq "$(JAVA_UNFINISHED)" "" in puzzles do perl -i~ -pe 'print "!srcdir unfinished/\n" if /!srcdir icons/' Recipe # Group is playable, even if still a bit unpolished and strange, so we
ifneq "$(JAVA_UNFINISHED)" "" in puzzles do ln -s unfinished/group.R . # can at least make the web versions of it (which are unobtrusive if
ifneq "$(JAVA_UNFINISHED)" "" in puzzles do perl mkfiles.pl # you don't deliberately navigate to the web pages).
set web_unfinished_option -DPUZZLES_ENABLE_UNFINISHED=group
ifneq "$(NOJAVA)" yes then ifneq "$(NOJAVA)" yes then
# Build the Java applets. # Build the Java applets.
delegate nestedvm delegate nestedvm
in puzzles do make -f Makefile.nestedvm NESTEDVM="$$NESTEDVM" VER=-DVER=$(Version) XFLAGS="-Wwrite-strings -Werror" -j$(nproc) in puzzles do cmake -B build-nestedvm -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=../cmake/nestedvm-toolchain.cmake -DNESTEDVM="$$NESTEDVM" $(web_unfinished_option) .
return puzzles/*.jar in puzzles/build-nestedvm do make -j$(nproc) VERBOSE=1
return puzzles/build-nestedvm/*.jar
return puzzles/build-nestedvm/unfinished/group.jar
enddelegate enddelegate
endif endif
@ -171,11 +123,11 @@ endif
# have the right dependencies installed for Emscripten, I do this by a # have the right dependencies installed for Emscripten, I do this by a
# delegation. # delegation.
ifneq "$(NOJS)" yes then ifneq "$(NOJS)" yes then
in puzzles do mkdir js # so we can tell output .js files from emcc*.js
delegate emscripten delegate emscripten
in puzzles do make -f Makefile.emcc OUTPREFIX=js/ clean in puzzles do emcmake cmake -B build-emscripten -DCMAKE_BUILD_TYPE=Release $(web_unfinished_option) .
in puzzles do make -f Makefile.emcc OUTPREFIX=js/ XFLAGS="-Wwrite-strings -Werror" -j$(nproc) in puzzles/build-emscripten do make -j$(nproc) VERBOSE=1
return puzzles/js/*.js return puzzles/build-emscripten/*.js
return puzzles/build-emscripten/unfinished/group.js
enddelegate enddelegate
# Build a set of wrapping HTML pages for easy testing of the # Build a set of wrapping HTML pages for easy testing of the
@ -198,7 +150,7 @@ in puzzles do echo RedirectMatch temp '(.*/)'puzzles-installer.msi '$$1'puzzles-
# Phew, we're done. Deliver everything! # Phew, we're done. Deliver everything!
ifneq "$(NOICONS)" yes then ifneq "$(NOICONS)" yes then
deliver puzzles/icons/*-web.png $@ deliver puzzles/build-icons/icons/*-web.png $@
endif endif
ifneq "$(NOWINDOWS)" yes then ifneq "$(NOWINDOWS)" yes then
deliver puzzles/winbin64/*.exe $@ deliver puzzles/winbin64/*.exe $@
@ -215,13 +167,15 @@ deliver puzzles/.htaccess $@
deliver puzzles/doc/*.html doc/$@ deliver puzzles/doc/*.html doc/$@
deliver puzzles/devel/*.html devel/$@ deliver puzzles/devel/*.html devel/$@
ifneq "$(NOMACOS)" yes then ifneq "$(NOMACOS)" yes then
deliver puzzles/Puzzles.dmg $@ deliver puzzles/build-osx/Puzzles.dmg $@
endif endif
ifneq "$(NOJAVA)" yes then ifneq "$(NOJAVA)" yes then
deliver puzzles/*.jar java/$@ deliver puzzles/build-nestedvm/*.jar java/$@
deliver puzzles/build-nestedvm/unfinished/*.jar java/$@
endif endif
ifneq "$(NOJS)" yes then ifneq "$(NOJS)" yes then
deliver puzzles/js/*.js js/$@ deliver puzzles/build-emscripten/*.js js/$@
deliver puzzles/build-emscripten/unfinished/*.js js/$@
deliver puzzles/jstest/*.html jstest/$@ deliver puzzles/jstest/*.html jstest/$@
deliver puzzles/html/*.html html/$@ deliver puzzles/html/*.html html/$@
deliver puzzles/html/*.pl html/$@ deliver puzzles/html/*.pl html/$@

View File

@ -6,20 +6,9 @@ Things to remember when adding a new puzzle
Write the source file for the new puzzle (duhh). Write the source file for the new puzzle (duhh).
Create a .R file for it which: Write a puzzle() statement in CMakeLists.txt containing all the
- defines a <puzzle>_EXTRA symbol for it if it requires auxiliary necessary metadata. Optionally also a solver() statement, and any
object files (make sure that symbol doesn't contain the icon) cliprogram() statements for extra auxiliary tools.
- adds it to the `ALL' definition, to ensure it is compiled into
the OS X binary
- adds it as a GTK build target, with the optional GTK icon
- adds it as a Windows build target, with the optional resource
file
- adds auxiliary solver binaries if any
- adds it to $(GAMES) in both the automake and GTK makefiles, for
`make install'
- adds it to list.c for the OS X binary
- adds it to gamedesc.txt, with its Windows executable name, display
name, and slightly longer description.
If the puzzle is by a new author, modify the copyright notice in 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 LICENCE and in puzzles.but. (Also in index.html, but that's listed
@ -47,15 +36,10 @@ html/<puzzlename>.html .
Make a screenshot: Make a screenshot:
- create an appropriate save file in `icons' - create an appropriate save file in `icons'
- add the puzzle name to icons/Makefile - define <puzzlename>_redo in icons/icons.cmake if the screenshot
- set up a REDO property in icons/Makefile if the screenshot wants wants to display a move halfway through an animation
to display a move halfway through an animation - define <puzzlename>_crop in icons/icons.cmake if the icon wants to
- set up a CROP property in icons/Makefile if the icon wants to be be a sub-rectangle of the whole screenshot
a sub-rectangle of the whole screenshot
Don't forget to `git add' the new source file, the new .R file and the
save file in `icons', the new .html file, and any other new files that
might have been involved.
Check in! Check in!

264
CMakeLists.txt Normal file
View File

@ -0,0 +1,264 @@
cmake_minimum_required(VERSION 3.16)
project(puzzles
LANGUAGES C)
include(cmake/setup.cmake)
add_library(common
combi.c divvy.c drawing.c dsf.c findloop.c grid.c latin.c
laydomino.c loopgen.c malloc.c matching.c midend.c misc.c penrose.c
ps.c random.c sort.c tdq.c tree234.c version.c
${platform_common_sources})
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
puzzle(blackbox
DISPLAYNAME "Black Box"
DESCRIPTION "Ball-finding puzzle"
OBJECTIVE "Find the hidden balls in the box by bouncing laser beams \
off them.")
puzzle(bridges
DISPLAYNAME "Bridges"
DESCRIPTION "Bridge-placing puzzle"
OBJECTIVE "Connect all the islands with a network of bridges.")
puzzle(cube
DISPLAYNAME "Cube"
DESCRIPTION "Rolling cube puzzle"
OBJECTIVE "Pick up all the blue squares by rolling the cube over them.")
puzzle(dominosa
DISPLAYNAME "Dominosa"
DESCRIPTION "Domino tiling puzzle"
OBJECTIVE "Tile the rectangle with a full set of dominoes.")
solver(dominosa)
puzzle(fifteen
DISPLAYNAME "Fifteen"
DESCRIPTION "Sliding block puzzle"
OBJECTIVE "Slide the tiles around to arrange them into order.")
solver(fifteen)
puzzle(filling
DISPLAYNAME "Filling"
DESCRIPTION "Polyomino puzzle"
OBJECTIVE "Mark every square with the area of its containing region.")
solver(filling)
puzzle(flip
DISPLAYNAME "Flip"
DESCRIPTION "Tile inversion puzzle"
OBJECTIVE "Flip groups of squares to light them all up at once.")
puzzle(flood
DISPLAYNAME "Flood"
DESCRIPTION "Flood-filling puzzle"
OBJECTIVE "Turn the grid the same colour in as few flood fills as possible.")
puzzle(galaxies
DISPLAYNAME "Galaxies"
DESCRIPTION "Symmetric polyomino puzzle"
OBJECTIVE "Divide the grid into rotationally symmetric regions each \
centred on a dot.")
solver(galaxies)
cliprogram(galaxiespicture galaxies.c
COMPILE_DEFINITIONS STANDALONE_PICTURE_GENERATOR)
puzzle(guess
DISPLAYNAME "Guess"
DESCRIPTION "Combination-guessing puzzle"
OBJECTIVE "Guess the hidden combination of colours.")
puzzle(inertia
DISPLAYNAME "Inertia"
DESCRIPTION "Gem-collecting puzzle"
OBJECTIVE "Collect all the gems without running into any of the mines.")
puzzle(keen
DISPLAYNAME "Keen"
DESCRIPTION "Arithmetic Latin square puzzle"
OBJECTIVE "Complete the latin square in accordance with the \
arithmetic clues.")
solver(keen latin.c)
puzzle(lightup
DISPLAYNAME "Light Up"
DESCRIPTION "Light-bulb placing puzzle"
OBJECTIVE "Place bulbs to light up all the squares.")
solver(lightup)
puzzle(loopy
DISPLAYNAME "Loopy"
DESCRIPTION "Loop-drawing puzzle"
OBJECTIVE "Draw a single closed loop, given clues about number of \
adjacent edges.")
solver(loopy)
puzzle(magnets
DISPLAYNAME "Magnets"
DESCRIPTION "Magnet-placing puzzle"
OBJECTIVE "Place magnets to satisfy the clues and avoid like poles \
touching.")
solver(magnets)
puzzle(map
DISPLAYNAME "Map"
DESCRIPTION "Map-colouring puzzle"
OBJECTIVE "Colour the map so that adjacent regions are never the \
same colour.")
solver(map)
puzzle(mines
DISPLAYNAME "Mines"
DESCRIPTION "Mine-finding puzzle"
OBJECTIVE "Find all the mines without treading on any of them.")
cliprogram(mineobfusc mines.c COMPILE_DEFINITIONS STANDALONE_OBFUSCATOR)
puzzle(net
# The Windows Net shouldn't be called 'net.exe', since Windows
# already has a reasonably important utility program by that name!
WINDOWS_EXE_NAME netgame
DISPLAYNAME "Net"
DESCRIPTION "Network jigsaw puzzle"
OBJECTIVE "Rotate each tile to reassemble the network.")
puzzle(netslide
DISPLAYNAME "Netslide"
DESCRIPTION "Toroidal sliding network puzzle"
OBJECTIVE "Slide a row at a time to reassemble the network.")
puzzle(nullgame)
puzzle(palisade
DISPLAYNAME "Palisade"
DESCRIPTION "Grid-division puzzle"
OBJECTIVE "Divide the grid into equal-sized areas in accordance with\
the clues.")
puzzle(pattern
DISPLAYNAME "Pattern"
DESCRIPTION "Pattern puzzle"
OBJECTIVE "Fill in the pattern in the grid, given only the lengths \
of runs of black squares.")
solver(pattern)
cliprogram(patternpicture pattern.c
COMPILE_DEFINITIONS STANDALONE_PICTURE_GENERATOR)
puzzle(pearl
DISPLAYNAME "Pearl"
DESCRIPTION "Loop-drawing puzzle"
OBJECTIVE "Draw a single closed loop, given clues about corner and \
straight squares.")
solver(pearl)
cliprogram(pearlbench pearl.c COMPILE_DEFINITIONS STANDALONE_SOLVER)
puzzle(pegs
DISPLAYNAME "Pegs"
DESCRIPTION "Peg solitaire puzzle"
OBJECTIVE "Jump pegs over each other to remove all but one.")
puzzle(range
DISPLAYNAME "Range"
DESCRIPTION "Visible-distance puzzle"
OBJECTIVE "Place black squares to limit the visible distance from \
each numbered cell.")
puzzle(rect
DISPLAYNAME "Rectangles"
DESCRIPTION "Rectangles puzzle"
OBJECTIVE "Divide the grid into rectangles with areas equal to the \
numbers.")
puzzle(samegame
DISPLAYNAME "Same Game"
DESCRIPTION "Block-clearing puzzle"
OBJECTIVE "Clear the grid by removing touching groups of the same \
colour squares.")
puzzle(signpost
DISPLAYNAME "Signpost"
DESCRIPTION "Square-connecting puzzle"
OBJECTIVE "Connect the squares into a path following the arrows.")
solver(signpost)
puzzle(singles
DISPLAYNAME "Singles"
DESCRIPTION "Number-removing puzzle"
OBJECTIVE "Black out the right set of duplicate numbers.")
solver(singles)
puzzle(sixteen
DISPLAYNAME "Sixteen"
DESCRIPTION "Toroidal sliding block puzzle"
OBJECTIVE "Slide a row at a time to arrange the tiles into order.")
puzzle(slant
DISPLAYNAME "Slant"
DESCRIPTION "Maze-drawing puzzle"
OBJECTIVE "Draw a maze of slanting lines that matches the clues.")
solver(slant)
puzzle(solo
DISPLAYNAME "Solo"
DESCRIPTION "Number placement puzzle"
OBJECTIVE "Fill in the grid so that each row, column and square \
block contains one of every digit.")
solver(solo)
puzzle(tents
DISPLAYNAME "Tents"
DESCRIPTION "Tent-placing puzzle"
OBJECTIVE "Place a tent next to each tree.")
solver(tents)
puzzle(towers
DISPLAYNAME "Towers"
DESCRIPTION "Tower-placing Latin square puzzle"
OBJECTIVE "Complete the latin square of towers in accordance with \
the clues.")
solver(towers latin.c)
puzzle(tracks
DISPLAYNAME "Tracks"
DESCRIPTION "Path-finding railway track puzzle"
OBJECTIVE "Fill in the railway track according to the clues.")
solver(tracks)
puzzle(twiddle
DISPLAYNAME "Twiddle"
DESCRIPTION "Rotational sliding block puzzle"
OBJECTIVE "Rotate the tiles around themselves to arrange them into order.")
puzzle(undead
DISPLAYNAME "Undead"
DESCRIPTION "Monster-placing puzzle"
OBJECTIVE "Place ghosts, vampires and zombies so that the right \
numbers of them can be seen in mirrors.")
puzzle(unequal
DISPLAYNAME "Unequal"
DESCRIPTION "Latin square puzzle"
OBJECTIVE "Complete the latin square in accordance with the > signs.")
solver(unequal latin.c)
puzzle(unruly
DISPLAYNAME "Unruly"
DESCRIPTION "Black and white grid puzzle"
OBJECTIVE "Fill in the black and white grid to avoid runs of three.")
solver(unruly)
puzzle(untangle
DISPLAYNAME "Untangle"
DESCRIPTION "Planar graph layout puzzle"
OBJECTIVE "Reposition the points so that the lines do not cross.")
add_subdirectory(unfinished)
cliprogram(obfusc obfusc.c)
cliprogram(latincheck latin.c COMPILE_DEFINITIONS STANDALONE_LATIN_TEST)
cliprogram(matching matching.c COMPILE_DEFINITIONS STANDALONE_MATCHING_TEST)
build_platform_extras()

46
README
View File

@ -2,48 +2,12 @@ This is the README accompanying the source code to Simon Tatham's
puzzle collection. The collection's web site is at puzzle collection. The collection's web site is at
<https://www.chiark.greenend.org.uk/~sgtatham/puzzles/>. <https://www.chiark.greenend.org.uk/~sgtatham/puzzles/>.
If you've obtained the source code by downloading a .tar.gz archive The puzzle collection is built using CMake <https://cmake.org/>. To
from the Puzzles web site, you should find several Makefiles in the compile in the simplest way (on any of Linux, Windows or Mac), run
source code. However, if you've checked the source code out from the these commands in the source directory:
Puzzles git repository, you won't find the Makefiles: they're
automatically generated by `mkfiles.pl', so run that to create them.
The Makefiles include: cmake .
cmake --build .
- `Makefile.am', together with the static `configure.ac', is intended
as input to automake. Run `mkauto.sh' to turn these into a
configure script and Makefile.in, after which you can then run
`./configure' to create an actual Unix Makefile.
- `Makefile.vc' should work under MS Visual C++ on Windows. Run
'nmake /f Makefile.vc' in a Visual Studio command prompt.
- `Makefile.cyg' should work under Cygwin / MinGW. With appropriate
tweaks and setting of TOOLPATH, it should work for both compiling
on Windows and cross-compiling on Unix.
- `Makefile.osx' should work under Mac OS X, provided the Xcode
tools are installed. It builds a single monolithic OS X
application capable of running any of the puzzles, or even more
than one of them at a time.
- `Makefile.wce' should work under MS eMbedded Visual C++ on
Windows and the Pocket PC SDK; it builds Pocket PC binaries.
Many of these Makefiles build a program called `nullgame' in
addition to the actual game binaries. This program doesn't do
anything; it's just a template for people to start from when adding
a new game to the collection, and it's compiled every time to ensure
that it _does_ compile and link successfully (because otherwise it
wouldn't be much use as a template). Once it's built, you can run it
if you really want to (but it's very boring), and then you should
ignore it.
DO NOT EDIT THE MAKEFILES DIRECTLY, if you plan to send any changes
back to the maintainer. The makefiles are generated automatically by
the Perl script `mkfiles.pl' from the file `Recipe' and the various
.R files. If you need to change the makefiles as part of a patch,
you should change Recipe, *.R, and/or mkfiles.pl.
The manual is provided in Windows Help format for the Windows build; The manual is provided in Windows Help format for the Windows build;
in text format for anyone who needs it; and in HTML for the Mac OS X in text format for anyone who needs it; and in HTML for the Mac OS X

171
Recipe
View File

@ -1,171 +0,0 @@
# -*- makefile -*-
#
# This file describes which puzzle binaries are made up from which
# object and resource files. It is processed into the various
# Makefiles by means of a Perl script. Makefile changes should
# really be made by editing this file and/or the Perl script, not
# by editing the actual Makefiles.
!name puzzles
!makefile gtk Makefile.gtk
!makefile am Makefile.am
!makefile vc Makefile.vc
!makefile wce Makefile.wce
!makefile cygwin Makefile.cyg
!makefile osx Makefile.osx
!makefile gnustep Makefile.gnustep
!makefile nestedvm Makefile.nestedvm
!makefile emcc Makefile.emcc
!makefile clangcl Makefile.clangcl
!srcdir icons/
WINDOWS_COMMON = printing
+ user32.lib gdi32.lib comctl32.lib comdlg32.lib winspool.lib
WINDOWS = windows WINDOWS_COMMON
COMMON = midend drawing misc malloc random version
GTK = gtk printing ps
# Objects needed for auxiliary command-line programs.
STANDALONE = nullfe random misc malloc
ALL = list
LATIN_DEPS = matching tree234
LATIN = latin LATIN_DEPS
LATIN_SOLVER = latin[STANDALONE_SOLVER] LATIN_DEPS
# 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
# Now each .R file adds part of the macro definition of GAMELIST to list.c.
!include *.R
# Then we finish up list.c as follows:
!begin >list.c
#define DECL(x) extern const game x;
#define REF(x) &x,
GAMELIST(DECL)
const game *gamelist[] = { GAMELIST(REF) };
const int gamecount = lenof(gamelist);
!end
# Unix standalone application for special-purpose obfuscation.
obfusc : [U] obfusc STANDALONE
# Test program built from latin.c.
latincheck : [U] latin[STANDALONE_LATIN_TEST] LATIN_DEPS STANDALONE
latincheck : [C] latin[STANDALONE_LATIN_TEST] LATIN_DEPS STANDALONE
# Test program built from matching.c.
matching : [U] matching[STANDALONE_MATCHING_TEST] tree234 STANDALONE
matching : [C] matching[STANDALONE_MATCHING_TEST] tree234 STANDALONE
puzzles : [G] windows[COMBINED] WINDOWS_COMMON COMMON ALL noicon.res
# Mac OS X unified application containing all the puzzles.
Puzzles : [MX] osx osx.icns osx-info.plist COMMON ALL
# For OS X, we must create the online help and include it in the
# application bundle.) Also we add -DCOMBINED to the compiler flags
# so as to inform the code that we're building a single binary for
# all the puzzles. Then I've also got some code in here to build a
# distributable .dmg disk image.
!begin osx
Puzzles_extra = Puzzles.app/Contents/Resources/Help/index.html
Puzzles.app/Contents/Resources/Help/index.html: \
Puzzles.app/Contents/Resources/Help osx-help.but puzzles.but
cd Puzzles.app/Contents/Resources/Help; \
halibut --html ../../../../osx-help.but ../../../../puzzles.but
Puzzles.app/Contents/Resources/Help: Puzzles.app/Contents/Resources
mkdir -p Puzzles.app/Contents/Resources/Help
release: Puzzles.dmg
Puzzles.dmg: Puzzles
rm -f raw.dmg
hdiutil create -megabytes 5 -layout NONE raw.dmg
hdid -nomount raw.dmg > devicename
newfs_hfs -v "Simon Tatham's Puzzle Collection" `cat devicename`
hdiutil eject `cat devicename`
hdid raw.dmg | cut -f1 -d' ' > devicename
cp -R Puzzles.app /Volumes/"Simon Tatham's Puzzle Collection"
hdiutil eject `cat devicename`
rm -f Puzzles.dmg
hdiutil convert -format UDCO raw.dmg -o Puzzles.dmg
rm -f raw.dmg devicename
!end
!begin am
bin_PROGRAMS = $(GAMES)
!end
!begin am_begin
GAMES =
!end
# make install for Unix.
!begin gtk
install:
for i in $(GAMES); do \
$(INSTALL_PROGRAM) -m 755 $(BINPREFIX)$$i $(DESTDIR)$(gamesdir)/$(BINPREFIX)$$i \
|| exit 1; \
done
!end
!begin nestedvm
%.tmpdir/PuzzleEngine.class: %.mips
mkdir -p $(patsubst %.mips,%,$<).tmpdir
cd $(patsubst %.mips,%,$<).tmpdir && \
java -cp $(NESTEDVM)/build:$(NESTEDVM)/upstream/build/classgen/build \
org.ibex.nestedvm.Compiler -outformat class -d . \
PuzzleEngine ../$<
org:
mkdir -p org/ibex/nestedvm/util
cp $(NESTEDVM)/build/org/ibex/nestedvm/Registers.class org/ibex/nestedvm
cp $(NESTEDVM)/build/org/ibex/nestedvm/UsermodeConstants.class org/ibex/nestedvm
cp $(NESTEDVM)/build/org/ibex/nestedvm/Runtime*.class org/ibex/nestedvm
cp $(NESTEDVM)/build/org/ibex/nestedvm/util/Platform*.class org/ibex/nestedvm/util
cp $(NESTEDVM)/build/org/ibex/nestedvm/util/Seekable*.class org/ibex/nestedvm/util
applet.manifest:
echo "Main-Class: PuzzleApplet" >applet.manifest
PuzzleApplet.class: PuzzleApplet.java org
javac -source 1.7 -target 1.7 PuzzleApplet.java
%.jar: %.tmpdir/PuzzleEngine.class PuzzleApplet.class applet.manifest org
cd $(patsubst %.jar,%,$@).tmpdir && ln -s ../applet.manifest ../org ../PuzzleApplet*.class .
cd $(patsubst %.jar,%,$@).tmpdir && jar cfm ../$@ applet.manifest PuzzleEngine.class PuzzleApplet*.class org
echo '<applet archive="'$@'" code="PuzzleApplet" width="700" height="500"></applet>' >$*.html
!end
# A benchmarking and testing target for the GTK puzzles.
!begin gtk
test: benchmark.html benchmark.txt
benchmark.html: benchmark.txt benchmark.pl
./benchmark.pl benchmark.txt > $@
benchmark.txt: benchmark.sh $(GAMES)
./benchmark.sh > $@
!end
!begin am
test: benchmark.html benchmark.txt
benchmark.html: benchmark.txt benchmark.pl
./benchmark.pl benchmark.txt > $@
benchmark.txt: benchmark.sh $(GAMES)
./benchmark.sh > $@
!end

View File

@ -1,19 +0,0 @@
# -*- makefile -*-
blackbox : [X] GTK COMMON blackbox blackbox-icon|no-icon
blackbox : [G] WINDOWS COMMON blackbox blackbox.res|noicon.res
ALL += blackbox[COMBINED]
!begin am gtk
GAMES += blackbox
!end
!begin >list.c
A(blackbox) \
!end
!begin >gamedesc.txt
blackbox:blackbox.exe:Black Box:Ball-finding puzzle:Find the hidden balls in the box by bouncing laser beams off them.
!end

View File

@ -1,21 +0,0 @@
# -*- makefile -*-
BRIDGES_EXTRA = dsf findloop
bridges : [X] GTK COMMON bridges BRIDGES_EXTRA bridges-icon|no-icon
bridges : [G] WINDOWS COMMON bridges BRIDGES_EXTRA bridges.res|noicon.res
ALL += bridges[COMBINED] BRIDGES_EXTRA
!begin am gtk
GAMES += bridges
!end
!begin >list.c
A(bridges) \
!end
!begin >gamedesc.txt
bridges:bridges.exe:Bridges:Bridge-placing puzzle:Connect all the islands with a network of bridges.
!end

65
cmake/glob-symlinks.py Executable file
View File

@ -0,0 +1,65 @@
#!/usr/bin/env python3
# Helper script used by the NestedVM cmake build script.
#
# Usage: glob-symlinks.py <srcdir> <wildcard> [<srcdir> <wildcard> ...]
#
# Each pair of command-line arguments is treated as a source
# directory, followed by either a single filename or a wildcard.
#
# The result is to create symlinks in the program's working directory
# mirroring all the files matched by the filenames/wildcards, each
# pointing at the appropriate source directory.
#
# For example, this command
# glob-symlinks.py /foo \*.txt /bar wibble.blah
# might create symlinks as follows:
# this.txt -> /foo/this.txt
# that.txt -> /foo/that.txt
# wibble.blah -> /bar/wibble.blah
#
# CMake could mostly do this itself, except that some of the files
# that need symlinking during the NestedVM build (to make a tree that
# we archive up into a .jar file) are Java class files with some
# '$suffix' in the name, and CMake doesn't escape the $ signs, so that
# the suffix vanishes during shell expansion.
import sys
import os
import glob
def get_arg_pairs():
args = iter(sys.argv)
next(args) # skip program name
while True:
try:
yield next(args), next(args)
except StopIteration:
break
def get_globbed_pairs():
for srcdir, pattern in get_arg_pairs():
if glob.escape(pattern) == pattern:
# Assume that unglobbed filenames exist
#print("non-glob:", srcdir, pattern)
yield srcdir, pattern
else:
#print("globbing:", srcdir, pattern)
prefix = srcdir + "/"
for filename in glob.iglob(prefix + pattern):
assert filename.startswith(prefix)
filename = filename[len(prefix):]
#print(" ->", srcdir, filename)
yield srcdir, filename
for srcdir, filename in get_globbed_pairs():
dirname = os.path.dirname(filename)
if len(dirname) > 0:
try:
os.makedirs(dirname)
except FileExistsError:
pass
try:
os.symlink(os.path.join(srcdir, filename), filename)
except FileExistsError:
pass

View File

@ -0,0 +1,10 @@
SET(CMAKE_SYSTEM_NAME NestedVM)
SET(CMAKE_SYSTEM_PROCESSOR mips)
SET(CMAKE_C_COMPILER ${NESTEDVM}/upstream/install/bin/mips-unknown-elf-gcc)
SET(CMAKE_FIND_ROOT_PATH ${NESTEDVM}/upstream/install)
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

View File

@ -0,0 +1,47 @@
set(platform_common_sources emcc.c)
set(platform_gui_libs)
set(platform_libs)
set(CMAKE_EXECUTABLE_SUFFIX ".js")
set(emcc_export_list
# Event handlers for mouse and keyboard input
_mouseup
_mousedown
_mousemove
_key
# Callback when the program activates timing
_timer_callback
# Callback from button presses in the UI outside the canvas
_command
# Game-saving and game-loading functions
_get_save_file
_free_save_file
_load_game
# Callbacks to return values from dialog boxes
_dlg_return_sval
_dlg_return_ival
# Callbacks when the resizing controls are used
_resize_puzzle
_restore_puzzle_size
# Main program, run at initialisation time
_main)
list(TRANSFORM emcc_export_list PREPEND \")
list(TRANSFORM emcc_export_list APPEND \")
string(JOIN "," emcc_export_string ${emcc_export_list})
set(CMAKE_C_LINK_FLAGS "-s ASM_JS=1 -s EXPORTED_FUNCTIONS='[${emcc_export_string}]'")
message("link=${CMAKE_C_LINK_EXECUTABLE}")
set(build_cli_programs FALSE)
function(get_platform_puzzle_extra_source_files OUTVAR NAME)
set(${OUTVAR} PARENT_SCOPE)
endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)
em_link_pre_js(${TARGET} ${CMAKE_SOURCE_DIR}/emccpre.js)
em_link_js_library(${TARGET} ${CMAKE_SOURCE_DIR}/emcclib.js)
endfunction()
function(build_platform_extras)
endfunction()

View File

@ -0,0 +1,60 @@
set(platform_common_sources nestedvm.c printing.c)
set(platform_libs -lm)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/applet.manifest
"Main-Class: PuzzleApplet\n")
include(FindJava)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/PuzzleApplet.class
COMMAND ${Java_JAVAC_EXECUTABLE}
-source 1.7 -target 1.7 -d . -cp ${NESTEDVM}/build
${CMAKE_SOURCE_DIR}/PuzzleApplet.java
DEPENDS ${CMAKE_SOURCE_DIR}/PuzzleApplet.java)
function(get_platform_puzzle_extra_source_files OUTVAR NAME)
set(${OUTVAR} PARENT_SCOPE)
endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)
set(build_subdir ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}-tmp)
add_custom_command(OUTPUT ${build_subdir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${build_subdir})
add_custom_command(OUTPUT ${build_subdir}/PuzzleApplet.class
COMMAND ${CMAKE_SOURCE_DIR}/cmake/glob-symlinks.py
${CMAKE_BINARY_DIR} applet.manifest
${CMAKE_BINARY_DIR} PuzzleApplet\\*.class
${NESTEDVM}/build org/ibex/nestedvm/Registers.class
${NESTEDVM}/build org/ibex/nestedvm/UsermodeConstants.class
${NESTEDVM}/build org/ibex/nestedvm/Runtime*.class
${NESTEDVM}/build org/ibex/nestedvm/util/Platform\\*.class
${NESTEDVM}/build org/ibex/nestedvm/util/Seekable\\*.class
WORKING_DIRECTORY ${build_subdir}
DEPENDS
${build_subdir}
${CMAKE_BINARY_DIR}/PuzzleApplet.class
${CMAKE_SOURCE_DIR}/cmake/glob-symlinks.py)
add_custom_command(OUTPUT ${build_subdir}/PuzzleEngine.class
COMMAND ${Java_JAVA_EXECUTABLE}
-cp ${NESTEDVM}/build:${NESTEDVM}/upstream/build/classgen/build
org.ibex.nestedvm.Compiler -outformat class -d .
PuzzleEngine ${CMAKE_CURRENT_BINARY_DIR}/${EXENAME}
DEPENDS
${build_subdir}
${CMAKE_CURRENT_BINARY_DIR}/${EXENAME}
WORKING_DIRECTORY ${build_subdir})
add_custom_target(${TARGET}-jar ALL
COMMAND ${Java_JAR_EXECUTABLE}
cfm ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.jar
applet.manifest PuzzleEngine.class PuzzleApplet*.class org
WORKING_DIRECTORY ${build_subdir}
DEPENDS
${CMAKE_BINARY_DIR}/PuzzleApplet.class
${build_subdir}/PuzzleApplet.class
${build_subdir}/PuzzleEngine.class)
endfunction()
function(build_platform_extras)
endfunction()

58
cmake/platforms/osx.cmake Normal file
View File

@ -0,0 +1,58 @@
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.6)
find_program(HALIBUT halibut REQUIRED)
set(CPACK_GENERATOR DragNDrop)
set(CPACK_PACKAGE_FILE_NAME Puzzles)
set(CPACK_DMG_VOLUME_NAME "Simon Tatham's Puzzle Collection")
include(CPack)
set(build_individual_puzzles FALSE)
function(get_platform_puzzle_extra_source_files OUTVAR NAME)
set(${OUTVAR} PARENT_SCOPE)
endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)
endfunction()
function(build_platform_extras)
write_generated_games_header()
set(resources
${CMAKE_CURRENT_SOURCE_DIR}/osx/Puzzles.icns)
set_source_files_properties(${resources} PROPERTIES
MACOSX_PACKAGE_LOCATION Resources)
add_executable(puzzles MACOSX_BUNDLE
osx.m list.c ${puzzle_sources}
${resources})
set_target_properties(puzzles PROPERTIES
OUTPUT_NAME Puzzles
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/osx/Info.plist)
target_compile_definitions(puzzles PRIVATE COMBINED)
target_include_directories(puzzles PRIVATE ${generated_include_dir})
target_link_libraries(puzzles common ${platform_gui_libs} ${platform_libs}
"-framework Cocoa")
get_property(bundle_basename TARGET puzzles PROPERTY OUTPUT_NAME)
set(help_dir ${CMAKE_CURRENT_BINARY_DIR}/${bundle_basename}.app/Contents/Resources/Help)
message(${help_dir})
add_custom_command(OUTPUT ${help_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${help_dir}
DEPENDS puzzles)
add_custom_command(OUTPUT ${help_dir}/index.html
COMMAND ${HALIBUT} --html
${CMAKE_CURRENT_SOURCE_DIR}/osx-help.but
${CMAKE_CURRENT_SOURCE_DIR}/puzzles.but
DEPENDS
${help_dir}
${CMAKE_CURRENT_SOURCE_DIR}/osx-help.but
${CMAKE_CURRENT_SOURCE_DIR}/puzzles.but
WORKING_DIRECTORY ${help_dir})
add_custom_target(osx_help ALL
DEPENDS ${help_dir}/index.html)
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Puzzles.app
USE_SOURCE_PERMISSIONS
DESTINATION .)
endfunction()

View File

@ -0,0 +1,68 @@
find_package(PkgConfig REQUIRED)
set(PUZZLES_GTK_FOUND FALSE)
macro(try_gtk_package VER PACKAGENAME)
if(NOT PUZZLES_GTK_FOUND AND
(NOT DEFINED PUZZLES_GTK_VERSION OR
PUZZLES_GTK_VERSION STREQUAL ${VER}))
pkg_check_modules(GTK ${PACKAGENAME})
if(GTK_FOUND)
set(PUZZLES_GTK_FOUND TRUE)
endif()
endif()
endmacro()
try_gtk_package(3 gtk+-3.0)
try_gtk_package(2 gtk+-2.0)
if(NOT PUZZLES_GTK_FOUND)
message(FATAL_ERROR "Unable to find any usable version of GTK.")
endif()
include_directories(${GTK_INCLUDE_DIRS})
link_directories(${GTK_LIBRARY_DIRS})
set(platform_common_sources gtk.c printing.c)
set(platform_gui_libs ${GTK_LIBRARIES})
set(platform_libs -lm)
set(build_icons TRUE)
function(try_append_cflag flag)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}")
try_compile(compile_passed ${CMAKE_BINARY_DIR}
SOURCES ${CMAKE_SOURCE_DIR}/cmake/testbuild.c
OUTPUT_VARIABLE test_compile_output
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${GTK_INCLUDE_DIRS}")
if(compile_passed)
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} PARENT_SCOPE)
endif()
endfunction()
if (CMAKE_C_COMPILER_ID MATCHES "GNU" OR
CMAKE_C_COMPILER_ID MATCHES "Clang")
try_append_cflag(-Wall)
try_append_cflag(-Werror)
try_append_cflag(-std=c89)
try_append_cflag(-pedantic)
try_append_cflag(-Wwrite-strings)
endif()
function(get_platform_puzzle_extra_source_files OUTVAR NAME)
if(build_icons AND EXISTS ${CMAKE_SOURCE_DIR}/icons/${NAME}.sav)
build_icon(${NAME})
set(c_icon_file ${CMAKE_BINARY_DIR}/icons/${NAME}-icon.c)
else()
set(c_icon_file ${CMAKE_SOURCE_DIR}/no-icon.c)
endif()
set(${OUTVAR} ${c_icon_file} PARENT_SCOPE)
endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)
install(TARGETS ${TARGET})
endfunction()
function(build_platform_extras)
endfunction()

View File

@ -0,0 +1,40 @@
set(platform_common_sources windows.c printing.c)
set(platform_gui_libs
user32.lib gdi32.lib comctl32.lib comdlg32.lib winspool.lib)
set(platform_libs)
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
function(get_platform_puzzle_extra_source_files OUTVAR NAME)
set(${OUTVAR} ${CMAKE_SOURCE_DIR}/puzzles.rc PARENT_SCOPE)
endfunction()
function(set_platform_puzzle_target_properties NAME TARGET)
if(DEFINED ICO_DIR AND EXISTS ${ICO_DIR}/${NAME}.ico)
target_compile_definitions(${TARGET} PRIVATE ICON_FILE=\"${ICO_DIR}/${NAME}.ico\")
endif()
set_target_properties(${TARGET} PROPERTIES WIN32_EXECUTABLE ON)
endfunction()
function(build_platform_extras)
write_generated_games_header()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gamedesc.txt "")
list(SORT puzzle_names)
foreach(name ${puzzle_names})
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/gamedesc.txt "\
${name}:\
${exename_${name}}.exe:\
${displayname_${name}}:\
${description_${name}}:\
${objective_${name}}\n")
endforeach()
add_executable(puzzles windows.c list.c ${puzzle_sources})
target_compile_definitions(puzzles PRIVATE COMBINED)
target_include_directories(puzzles PRIVATE ${generated_include_dir})
target_link_libraries(puzzles common ${platform_gui_libs} ${platform_libs})
set_target_properties(puzzles PROPERTIES WIN32_EXECUTABLE ON)
endfunction()

133
cmake/setup.cmake Normal file
View File

@ -0,0 +1,133 @@
set(build_individual_puzzles TRUE)
set(build_cli_programs TRUE)
set(build_icons FALSE)
set(need_c_icons FALSE)
# Include one of platforms/*.cmake to define platform-specific stuff.
# Each of these is expected to:
# - define get_platform_puzzle_extra_source_files(), used below
# - define set_platform_puzzle_target_properties(), used below
# - define build_platform_extras(), called from the top-level CMakeLists.txt
# - override the above build_* settings, if necessary
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
include(cmake/platforms/windows.cmake)
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
include(cmake/platforms/osx.cmake)
elseif(CMAKE_SYSTEM_NAME MATCHES "NestedVM")
include(cmake/platforms/nestedvm.cmake)
elseif(CMAKE_C_COMPILER MATCHES "emcc")
include(cmake/platforms/emscripten.cmake)
else() # assume Unix
include(cmake/platforms/unix.cmake)
endif()
# Accumulate lists of the puzzles' bare names and source file
# locations, for use in build_platform_extras() implementations when
# they want to build things based on all the puzzles at once.
set(puzzle_names)
set(puzzle_sources)
include(icons/icons.cmake)
# The main function called from the top-level CMakeLists.txt to define
# each puzzle.
function(puzzle NAME)
cmake_parse_arguments(OPT
"" "DISPLAYNAME;DESCRIPTION;OBJECTIVE;WINDOWS_EXE_NAME" "" ${ARGN})
if(NOT DEFINED OPT_WINDOWS_EXE_NAME)
set(OPT_WINDOWS_EXE_NAME ${NAME})
endif()
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(EXENAME ${OPT_WINDOWS_EXE_NAME})
else()
set(EXENAME ${NAME})
endif()
set(exename_${NAME} ${EXENAME} PARENT_SCOPE)
set(displayname_${NAME} ${OPT_DISPLAYNAME} PARENT_SCOPE)
set(description_${NAME} ${OPT_DESCRIPTION} PARENT_SCOPE)
set(objective_${NAME} ${OPT_OBJECTIVE} PARENT_SCOPE)
set(official TRUE)
if(NAME STREQUAL nullgame)
# nullgame is not a playable puzzle; it has to be built (to prove
# it still can build), but not installed, or included in the main
# list of puzzles, or compiled into all-in-one binaries, etc. In
# other words, it's not "officially" part of the puzzle
# collection.
set(official FALSE)
endif()
if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_SOURCE_DIR}/unfinished)
# The same goes for puzzles in the 'unfinished' subdirectory,
# although we make an exception if configured to on the command
# line.
list(FIND PUZZLES_ENABLE_UNFINISHED ${NAME} enable_this_one)
if(enable_this_one EQUAL -1)
set(official FALSE)
endif()
endif()
if (official)
set(puzzle_names ${puzzle_names} ${NAME} PARENT_SCOPE)
set(puzzle_sources ${puzzle_sources} ${CMAKE_CURRENT_SOURCE_DIR}/${NAME}.c PARENT_SCOPE)
endif()
get_platform_puzzle_extra_source_files(extra_files ${NAME})
if (build_individual_puzzles)
add_executable(${EXENAME} ${NAME}.c ${extra_files})
target_link_libraries(${EXENAME}
common ${platform_gui_libs} ${platform_libs})
set_platform_puzzle_target_properties(${NAME} ${EXENAME})
endif()
endfunction()
# The main function called from the top-level CMakeLists.txt to define
# a command-line helper tool.
function(cliprogram NAME)
cmake_parse_arguments(OPT
"" "COMPILE_DEFINITIONS" "" ${ARGN})
if(build_cli_programs)
add_executable(${NAME} ${CMAKE_SOURCE_DIR}/nullfe.c
${OPT_UNPARSED_ARGUMENTS})
target_link_libraries(${NAME} common ${platform_libs})
if(OPT_COMPILE_DEFINITIONS)
target_compile_definitions(${NAME} PRIVATE ${OPT_COMPILE_DEFINITIONS})
endif()
endif()
endfunction()
# A small wrapper around cliprogram, taking advantage of the common
# formula that puzzle 'foo' often comes with 'foosolver'.
function(solver NAME)
cliprogram(${NAME}solver ${puzzle_src_prefix}${NAME}.c ${ARGN}
COMPILE_DEFINITIONS STANDALONE_SOLVER)
endfunction()
function(write_generated_games_header)
set(generated_include_dir ${CMAKE_CURRENT_BINARY_DIR}/include)
set(generated_include_dir ${generated_include_dir} PARENT_SCOPE)
file(MAKE_DIRECTORY ${generated_include_dir})
file(WRITE ${generated_include_dir}/generated-games.h "")
list(SORT puzzle_names)
foreach(name ${puzzle_names})
file(APPEND ${generated_include_dir}/generated-games.h "GAME(${name})\n")
endforeach()
endfunction()
# This has to be run from the unfinished subdirectory, so that the
# updates to puzzle_names etc will be propagated to the top-level scope.
macro(export_variables_to_parent_scope)
set(puzzle_names ${puzzle_names} PARENT_SCOPE)
set(puzzle_sources ${puzzle_sources} PARENT_SCOPE)
foreach(name ${puzzle_names})
set(exename_${name} ${exename_${name}} PARENT_SCOPE)
set(displayname_${name} ${displayname_${name}} PARENT_SCOPE)
set(description_${name} ${description_${name}} PARENT_SCOPE)
set(objective_${name} ${objective_${name}} PARENT_SCOPE)
endforeach()
endmacro()

23
cmake/testbuild.c Normal file
View File

@ -0,0 +1,23 @@
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
int dummy;

View File

@ -0,0 +1,14 @@
# Fake CMake toolchain file, good enough to make cmake's initial
# configuration think it's going to build for Windows, but not good
# enough to actually do any building. The purpose is so that I can run
# Puzzles's CMakeLists.txt in Windows mode as far as making
# gamedesc.txt.
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_C_COMPILER /bin/false)
set(CMAKE_LINKER /bin/false)
set(CMAKE_MT /bin/false)
set(CMAKE_RC_COMPILER /bin/false)
set(CMAKE_C_COMPILER_WORKS ON)

View File

@ -1,85 +0,0 @@
dnl Configure script for the Unix GTK build of puzzles.
AC_INIT([puzzles], [6.66], [anakin@pobox.com])
AC_CONFIG_SRCDIR([midend.c])
AM_INIT_AUTOMAKE([foreign])
AC_PROG_CC
AC_ARG_WITH([gtk],
[AS_HELP_STRING([--with-gtk=VER],
[specify GTK version to use (`2' or `3')])],
[gtk_version_desired="$withval"],
[gtk_version_desired="any"])
case "$gtk_version_desired" in
2 | 3 | any) ;;
yes) gtk_version_desired="any" ;;
*) AC_ERROR([Invalid GTK version specified])
esac
gtk=none
case "$gtk_version_desired:$gtk" in
3:none | any:none)
ifdef([AM_PATH_GTK_3_0],[
AM_PATH_GTK_3_0([3.0.0], [gtk=3], [])
],[AC_WARNING([generating configure script without GTK 3 autodetection])])
;;
esac
case "$gtk_version_desired:$gtk" in
2:none | any:none)
ifdef([AM_PATH_GTK_2_0],[
AM_PATH_GTK_2_0([2.0.0], [gtk=2], [])
],[AC_WARNING([generating configure script without GTK 2 autodetection])])
;;
esac
if test "$gtk" = "none"; then
AC_MSG_ERROR([cannot build without GTK 2 or GTK 3])
fi
if test "x$GCC" = "xyes"; then
AC_MSG_CHECKING([for usable gcc warning flags])
gccwarningflags=
for flag in -Wall -Werror -std=c89 -pedantic; do
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS$gccwarningflags $flag $GTK_CFLAGS"
LIBS="$GTK_LIBS $LIBS"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
],[
return 0;
])], [gccwarningflags="$gccwarningflags $flag"], [])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
done
AC_MSG_RESULT($gccwarningflags)
CFLAGS="$CFLAGS$gccwarningflags"
fi
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

19
cube.R
View File

@ -1,19 +0,0 @@
# -*- makefile -*-
cube : [X] GTK COMMON cube cube-icon|no-icon
cube : [G] WINDOWS COMMON cube cube.res|noicon.res
ALL += cube[COMBINED]
!begin am gtk
GAMES += cube
!end
!begin >list.c
A(cube) \
!end
!begin >gamedesc.txt
cube:cube.exe:Cube:Rolling cube puzzle:Pick up all the blue squares by rolling the cube over them.
!end

View File

@ -4441,15 +4441,11 @@ So start by copying \c{nullgame.c} into your new source file. Then
you'll gradually add functionality until the very boring Null Game you'll gradually add functionality until the very boring Null Game
turns into your real game. turns into your real game.
Next you'll need to add your puzzle to the Makefiles, in order to Next you'll need to add your puzzle to the build scripts, in order to
compile it conveniently. \e{Do not edit the Makefiles}: they are compile it conveniently. Puzzles is a CMake project, so you do this by
created automatically by the script \c{mkfiles.pl}, from the file adding a \cw{puzzle()} statement to CMakeLists.txt. Look at the
called \c{Recipe}. Edit \c{Recipe}, and then re-run \c{mkfiles.pl}. existing ones to see what those look like, and add one that looks
similar.
Also, don't forget to add your puzzle to \c{list.c}: if you don't,
then it will still run fine on platforms which build each puzzle
separately, but Mac OS X and other monolithic platforms will not
include your new puzzle in their single binary.
Once your source file is building, you can move on to the fun bit. Once your source file is building, you can move on to the fun bit.

View File

@ -1,24 +0,0 @@
# -*- makefile -*-
DOMINOSA_EXTRA = laydomino dsf sort findloop
dominosa : [X] GTK COMMON dominosa DOMINOSA_EXTRA dominosa-icon|no-icon
dominosa : [G] WINDOWS COMMON dominosa DOMINOSA_EXTRA dominosa.res|noicon.res
ALL += dominosa[COMBINED] DOMINOSA_EXTRA
dominosasolver : [U] dominosa[STANDALONE_SOLVER] DOMINOSA_EXTRA STANDALONE
dominosasolver : [C] dominosa[STANDALONE_SOLVER] DOMINOSA_EXTRA STANDALONE
!begin am gtk
GAMES += dominosa
!end
!begin >list.c
A(dominosa) \
!end
!begin >gamedesc.txt
dominosa:dominosa.exe:Dominosa:Domino tiling puzzle:Tile the rectangle with a full set of dominoes.
!end

View File

@ -1,33 +0,0 @@
// -*- js -*-
//
// List of entry points exported by the C side of the Emscripten
// puzzle builds. Passed in to emcc via the option '-s
// EXPORTED_FUNCTIONS=[list]'.
//
// This file isn't actually a valid list in its current state, since
// emcc doesn't like comments or newlines. However, it's a nicer
// source form to keep the comments and newlines in, so we sed them
// away at compile time.
[
// Event handlers for mouse and keyboard input
'_mouseup',
'_mousedown',
'_mousemove',
'_key',
// Callback when the program activates timing
'_timer_callback',
// Callback from button presses in the UI outside the canvas
'_command',
// Game-saving and game-loading functions
'_get_save_file',
'_free_save_file',
'_load_game',
// Callbacks to return values from dialog boxes
'_dlg_return_sval',
'_dlg_return_ival',
// Callbacks when the resizing controls are used
'_resize_puzzle',
'_restore_puzzle_size',
// Main program, run at initialisation time
'_main'
]

View File

@ -1,22 +0,0 @@
# -*- makefile -*-
fifteen : [X] GTK COMMON fifteen fifteen-icon|no-icon
fifteen : [G] WINDOWS COMMON fifteen fifteen.res|noicon.res
fifteensolver : [U] fifteen[STANDALONE_SOLVER] STANDALONE
fifteensolver : [C] fifteen[STANDALONE_SOLVER] STANDALONE
ALL += fifteen[COMBINED]
!begin am gtk
GAMES += fifteen
!end
!begin >list.c
A(fifteen) \
!end
!begin >gamedesc.txt
fifteen:fifteen.exe:Fifteen:Sliding block puzzle:Slide the tiles around to arrange them into order.
!end

View File

@ -1,24 +0,0 @@
# -*- makefile -*-
FILLING_EXTRA = dsf
fillingsolver : [U] filling[STANDALONE_SOLVER] FILLING_EXTRA STANDALONE
fillingsolver : [C] filling[STANDALONE_SOLVER] FILLING_EXTRA STANDALONE
filling : [X] GTK COMMON filling FILLING_EXTRA filling-icon|no-icon
filling : [G] WINDOWS COMMON filling FILLING_EXTRA filling.res|noicon.res
ALL += filling[COMBINED] FILLING_EXTRA
!begin am gtk
GAMES += filling
!end
!begin >list.c
A(filling) \
!end
!begin >gamedesc.txt
filling:filling.exe:Filling:Polyomino puzzle:Mark every square with the area of its containing region.
!end

21
flip.R
View File

@ -1,21 +0,0 @@
# -*- makefile -*-
FLIP_EXTRA = tree234
flip : [X] GTK COMMON flip FLIP_EXTRA flip-icon|no-icon
flip : [G] WINDOWS COMMON flip FLIP_EXTRA flip.res|noicon.res
ALL += flip[COMBINED] FLIP_EXTRA
!begin am gtk
GAMES += flip
!end
!begin >list.c
A(flip) \
!end
!begin >gamedesc.txt
flip:flip.exe:Flip:Tile inversion puzzle:Flip groups of squares to light them all up at once.
!end

19
flood.R
View File

@ -1,19 +0,0 @@
# -*- makefile -*-
flood : [X] GTK COMMON flood flood-icon|no-icon
flood : [G] WINDOWS COMMON flood flood.res|noicon.res
ALL += flood[COMBINED]
!begin am gtk
GAMES += flood
!end
!begin >list.c
A(flood) \
!end
!begin >gamedesc.txt
flood:flood.exe:Flood:Flood-filling puzzle:Turn the grid the same colour in as few flood fills as possible.
!end

View File

@ -1,28 +0,0 @@
# -*- makefile -*-
GALAXIES_EXTRA = dsf
galaxies : [X] GTK COMMON galaxies GALAXIES_EXTRA galaxies-icon|no-icon
galaxies : [G] WINDOWS COMMON galaxies GALAXIES_EXTRA galaxies.res|noicon.res
galaxiessolver : [U] galaxies[STANDALONE_SOLVER] GALAXIES_EXTRA STANDALONE m.lib
galaxiessolver : [C] galaxies[STANDALONE_SOLVER] GALAXIES_EXTRA STANDALONE
galaxiespicture : [U] galaxies[STANDALONE_PICTURE_GENERATOR] GALAXIES_EXTRA STANDALONE
+ m.lib
galaxiespicture : [C] galaxies[STANDALONE_PICTURE_GENERATOR] GALAXIES_EXTRA STANDALONE
ALL += galaxies[COMBINED] GALAXIES_EXTRA
!begin am gtk
GAMES += galaxies
!end
!begin >list.c
A(galaxies) \
!end
!begin >gamedesc.txt
galaxies:galaxies.exe:Galaxies:Symmetric polyomino puzzle:Divide the grid into rotationally symmetric regions each centred on a dot.
!end

19
guess.R
View File

@ -1,19 +0,0 @@
# -*- makefile -*-
guess : [X] GTK COMMON guess guess-icon|no-icon
guess : [G] WINDOWS COMMON guess guess.res|noicon.res
ALL += guess[COMBINED]
!begin am gtk
GAMES += guess
!end
!begin >list.c
A(guess) \
!end
!begin >gamedesc.txt
guess:guess.exe:Guess:Combination-guessing puzzle:Guess the hidden combination of colours.
!end

View File

@ -1,162 +0,0 @@
# 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))
P96D24 = $(patsubst %,%-96d24.png,$(PUZZLES))
P96D8 = $(patsubst %,%-96d8.png,$(PUZZLES))
P96D4 = $(patsubst %,%-96d4.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: $(P96D24) $(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 four sizes.
$(P96D24): %-96d24.png: %-ibase.png
$(PIC)square.pl 96 4 $^ $@
$(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.
$(P96D8) $(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...)
$(P96D4): %-96d4.png: %-ibase4.png
$(PIC)square.pl 96 1 $^ $@-tmp2.png
convert -colors 16 $(CSP) -map $(PIC)win16pal.xpm $@-tmp2.png $@
rm -f $@-tmp2.png
$(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 %-96d24.png
$(PIC)cicon.pl $^ > $@
clean:
rm -f *.png *.ico *.rc *-icon.c

View File

@ -5,12 +5,13 @@
$k = 0; $k = 0;
@xpms = (); @xpms = ();
$convert = shift @ARGV;
foreach $f (@ARGV) { foreach $f (@ARGV) {
# XPM format is generated directly by ImageMagick, so that's easy # XPM format is generated directly by ImageMagick, so that's easy
# enough. We just have to adjust the declaration line so that it # enough. We just have to adjust the declaration line so that it
# has the right name, linkage and storage class. # has the right name, linkage and storage class.
@lines = (); @lines = ();
open XPM, "convert $f xpm:- |"; open XPM, "-|", $convert, $f, "xpm:-";
push @lines, $_ while <XPM>; push @lines, $_ while <XPM>;
close XPM; close XPM;
die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/; die "XPM from $f in unexpected format\n" unless $lines[1] =~ /^static.*\{$/;

View File

@ -13,25 +13,27 @@
# this script will give a build error and alert me to the fact that # this script will give a build error and alert me to the fact that
# I need to fiddle with the icon makefile. # I need to fiddle with the icon makefile.
infile="$1" identify="$1"
outfile="$2" convert="$2"
insize="$3" infile="$3"
crop="$4" outfile="$4"
insize="$5"
crop="$6"
# Special case: if no input size or crop parameter was specified at # Special case: if no input size or crop parameter was specified at
# all, we just copy the input to the output file. # all, we just copy the input to the output file.
if test $# -lt 3; then if test -z "$insize"; then
cp "$infile" "$outfile" cp "$infile" "$outfile"
exit 0 exit 0
fi fi
# Check the input image size. # Check the input image size.
realsize=`identify -format %wx%h "$infile"` realsize=$("$identify" -format %wx%h "$infile")
if test "x$insize" != "x$realsize"; then if test "x$insize" != "x$realsize"; then
echo "crop.sh: '$infile' has wrong initial size: $realsize != $insize" >&2 echo "crop.sh: '$infile' has wrong initial size: $realsize != $insize" >&2
exit 1 exit 1
fi fi
# And crop. # And crop.
convert -crop "$crop" "$infile" "$outfile" "$convert" -crop "$crop" "$infile" "$outfile"

View File

@ -85,9 +85,12 @@
@dat = (); @dat = ();
$depth = undef; $depth = undef;
$convert = "convert";
foreach $_ (@ARGV) { foreach $_ (@ARGV) {
if (/^-(24|8|4|1)$/) { if (/^-(24|8|4|1)$/) {
$depth = $1; $depth = $1;
} elsif (/^--convert=(.*)$/) {
$convert = $1;
} elsif (defined $depth) { } elsif (defined $depth) {
&readicon($_, $depth); &readicon($_, $depth);
} else { } else {
@ -127,7 +130,7 @@ sub readicon {
# point, to avoid having to do it ourselves (.BMP and hence # point, to avoid having to do it ourselves (.BMP and hence
# .ICO are bottom-up). # .ICO are bottom-up).
my $data = []; my $data = [];
open IDATA, "convert -set colorspace sRGB -flip -depth 8 $filename rgba:- |"; open IDATA, "-|", $convert, "-set", "colorspace", "sRGB", "-flip", "-depth", "8", $filename, "rgba:-";
push @$data, $rgb while (read IDATA,$rgb,4,0) == 4; push @$data, $rgb while (read IDATA,$rgb,4,0) == 4;
close IDATA; close IDATA;
# Check we have the right amount of data. # Check we have the right amount of data.

237
icons/icons.cmake Normal file
View File

@ -0,0 +1,237 @@
if(NOT build_icons)
# This entire subdirectory does nothing on platforms where we can't
# build the icons in any case.
return()
endif()
find_program(CONVERT convert REQUIRED)
find_program(IDENTIFY identify REQUIRED)
# For puzzles which have animated moves, it's nice to show the sample
# image part way through the animation of a move. This setting will
# cause a 'redo' action immediately after loading the save file,
# causing the first undone move in the undo chain to be redone, and
# then it will stop this far through the move animation to take the
# screenshot.
set(fifteen_redo 0.3)
set(flip_redo 0.3)
set(netslide_redo 0.3)
set(sixteen_redo 0.3)
set(twiddle_redo 0.3)
# For many puzzles, we'd prefer that the icon zooms in on a couple of
# squares of the playing area rather than trying to show the whole of
# a game. These settings configure that. Each one indicates the
# expected full size of the screenshot image, followed by the area we
# want to crop to.
#
# (The expected full size is a safety precaution: if a puzzle changes
# its default display size, then that won't match, and we'll get a
# build error here rather than silently continuing to take the wrong
# subrectangle of the resized puzzle display.)
set(blackbox_crop 352x352 144x144+0+208)
set(bridges_crop 264x264 107x107+157+157)
set(dominosa_crop 304x272 152x152+152+0)
set(fifteen_crop 240x240 120x120+0+120)
set(filling_crop 256x256 133x133+14+78)
set(flip_crop 288x288 145x145+120+72)
set(galaxies_crop 288x288 165x165+0+0)
set(guess_crop 263x420 178x178+75+17)
set(inertia_crop 321x321 128x128+193+0)
set(keen_crop 288x288 96x96+24+120)
set(lightup_crop 256x256 112x112+144+0)
set(loopy_crop 257x257 113x113+0+0)
set(magnets_crop 264x232 96x96+36+100)
set(mines_crop 240x240 110x110+130+130)
set(net_crop 193x193 113x113+0+80)
set(netslide_crop 289x289 144x144+0+0)
set(palisade_crop 288x288 192x192+0+0)
set(pattern_crop 384x384 223x223+0+0)
set(pearl_crop 216x216 94x94+108+15)
set(pegs_crop 263x263 147x147+116+0)
set(range_crop 256x256 98x98+111+15)
set(rect_crop 205x205 115x115+90+0)
set(signpost_crop 240x240 98x98+23+23)
set(singles_crop 224x224 98x98+15+15)
set(sixteen_crop 288x288 144x144+144+144)
set(slant_crop 321x321 160x160+160+160)
set(solo_crop 481x481 145x145+24+24)
set(tents_crop 320x320 165x165+142+0)
set(towers_crop 300x300 102x102+151+6)
set(tracks_crop 246x246 118x118+6+6)
set(twiddle_crop 192x192 102x102+69+21)
set(undead_crop 416x480 192x192+16+80)
set(unequal_crop 208x208 104x104+104+104)
set(untangle_crop 320x320 164x164+3+116)
add_custom_target(icons)
# All sizes of icon we make for any purpose.
set(all_icon_sizes 96 48 32 16)
# Sizes of icon we put into the Windows .ico files.
set(win_icon_sizes 48 32 16)
# Border thickness for each icon size.
set(border_96 4)
set(border_48 4)
set(border_32 2)
set(border_16 1)
set(icon_srcdir ${CMAKE_SOURCE_DIR}/icons)
set(icon_bindir ${CMAKE_BINARY_DIR}/icons)
function(build_icon name)
set(output_icon_files)
# Compile the GTK puzzle binary without an icon, so that we can run
# it to generate a screenshot to make the icon out of.
add_executable(${NAME}-icon-maker ${NAME}.c
${CMAKE_SOURCE_DIR}/no-icon.c)
target_link_libraries(${NAME}-icon-maker
common ${platform_gui_libs} ${platform_libs})
set_target_properties(${NAME}-icon-maker PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${icon_bindir})
# Now run that binary to generate a screenshot of the puzzle in
# play, which will be the base image we make everything else out
# out.
if(DEFINED ${name}_redo)
set(redo_arg --redo ${name}_redo)
else()
set(redo_arg)
endif()
add_custom_command(OUTPUT ${icon_bindir}/${name}-base.png
COMMAND ${icon_bindir}/${name}-icon-maker
${redo_arg}
--screenshot ${icon_bindir}/${name}-base.png
--load ${icon_srcdir}/${name}.sav
DEPENDS
${name}-icon-maker)
# Shrink it to a fixed-size square image for the web page,
# trimming boring border parts of the original image in the
# process. Done by square.pl.
add_custom_command(OUTPUT ${icon_bindir}/${name}-web.png
COMMAND ${icon_srcdir}/square.pl
${CONVERT} 150 5
${icon_bindir}/${name}-base.png
${icon_bindir}/${name}-web.png
DEPENDS
${icon_srcdir}/square.pl
${icon_bindir}/${name}-base.png)
list(APPEND output_icon_files ${icon_bindir}/${name}-web.png)
# Make the base image for all the icons, by cropping out the most
# interesting part of the whole screenshot.
add_custom_command(OUTPUT ${icon_bindir}/${name}-ibase.png
COMMAND ${icon_srcdir}/crop.sh
${IDENTIFY} ${CONVERT}
${icon_bindir}/${name}-base.png
${icon_bindir}/${name}-ibase.png
${${name}_crop}
DEPENDS
${icon_srcdir}/crop.sh
${icon_bindir}/${name}-base.png)
# Coerce that base image down to colour depth of 4 bits, using the
# fixed 16-colour Windows palette. We do this before shrinking the
# image, because I've found that gives better results than just
# doing it after.
add_custom_command(OUTPUT ${icon_bindir}/${name}-ibase4.png
COMMAND ${CONVERT}
-colors 16
+dither
-set colorspace RGB
-map ${icon_srcdir}/win16pal.xpm
${icon_bindir}/${name}-ibase.png
${icon_bindir}/${name}-ibase4.png
DEPENDS
${icon_srcdir}/win16pal.xpm
${icon_bindir}/${name}-ibase.png)
foreach(size ${all_icon_sizes})
# Make a 24-bit icon image at each size, by shrinking the base
# icon image.
add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d24.png
COMMAND ${icon_srcdir}/square.pl
${CONVERT} ${size} ${border_${size}}
${icon_bindir}/${name}-ibase.png
${icon_bindir}/${name}-${size}d24.png
DEPENDS
${icon_srcdir}/square.pl
${icon_bindir}/${name}-ibase.png)
list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d24.png)
# And reduce the colour depth of that one to make an 8-bit
# version.
add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d8.png
COMMAND ${CONVERT}
-colors 256
${icon_bindir}/${name}-${size}d24.png
${icon_bindir}/${name}-${size}d8.png
DEPENDS ${icon_bindir}/${name}-${size}d24.png)
list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d8.png)
endforeach()
foreach(size ${win_icon_sizes})
# 4-bit icons are only needed for Windows. We make each one by
# first shrinking the large 4-bit image we made above ...
add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d4pre.png
COMMAND ${icon_srcdir}/square.pl
${CONVERT} ${size} ${border_${size}}
${icon_bindir}/${name}-ibase4.png
${icon_bindir}/${name}-${size}d4pre.png
DEPENDS
${icon_srcdir}/square.pl
${icon_bindir}/${name}-ibase4.png)
# ... and then re-coercing the output back to 16 colours, since
# that shrink operation will have introduced intermediate colour
# values again.
add_custom_command(OUTPUT ${icon_bindir}/${name}-${size}d4.png
COMMAND ${CONVERT}
-colors 16
+dither
-set colorspace RGB
-map ${icon_srcdir}/win16pal.xpm
${icon_bindir}/${name}-${size}d4pre.png
${icon_bindir}/${name}-${size}d4.png
DEPENDS ${icon_bindir}/${name}-${size}d4pre.png)
list(APPEND output_icon_files ${icon_bindir}/${name}-${size}d4.png)
endforeach()
# Make the Windows icon.
set(icon_pl_args)
set(icon_pl_deps)
foreach(depth 24 8 4)
list(APPEND icon_pl_args -${depth})
foreach(size ${win_icon_sizes})
list(APPEND icon_pl_args ${icon_bindir}/${name}-${size}d${depth}.png)
list(APPEND icon_pl_deps ${icon_bindir}/${name}-${size}d${depth}.png)
endforeach()
endforeach()
add_custom_command(OUTPUT ${icon_bindir}/${name}.ico
COMMAND ${icon_srcdir}/icon.pl
--convert=${CONVERT}
${icon_pl_args} > ${icon_bindir}/${name}.ico
DEPENDS
${icon_srcdir}/icon.pl
${icon_pl_deps})
list(APPEND output_icon_files ${icon_bindir}/${name}.ico)
# Make a C source file containing XPMs of all the 24-bit images.
set(cicon_pl_infiles)
foreach(size ${all_icon_sizes})
list(APPEND cicon_pl_infiles ${icon_bindir}/${name}-${size}d24.png)
endforeach()
add_custom_command(OUTPUT ${icon_bindir}/${name}-icon.c
COMMAND ${icon_srcdir}/cicon.pl
${CONVERT} ${cicon_pl_infiles} > ${icon_bindir}/${name}-icon.c
DEPENDS
${icon_srcdir}/cicon.pl
${cicon_pl_infiles})
add_custom_target(${name}-icons DEPENDS ${output_icon_files})
add_dependencies(icons ${name}-icons)
endfunction()

View File

@ -1,25 +0,0 @@
#!/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"

View File

@ -8,7 +8,7 @@
# - the input image file name # - the input image file name
# - the output image file name. # - the output image file name.
($osize, $oborder, $infile, $outfile) = @ARGV; ($convert, $osize, $oborder, $infile, $outfile) = @ARGV;
# Determine the input image's size. # Determine the input image's size.
$ident = `identify -format "%w %h" $infile`; $ident = `identify -format "%w %h" $infile`;
@ -17,7 +17,7 @@ $ident =~ /(\d+) (\d+)/ or die "unable to get size for $infile\n";
# Read the input image data. # Read the input image data.
$data = []; $data = [];
open IDATA, "convert -depth 8 $infile rgb:- |"; open IDATA, "-|", $convert, "-depth", "8", $infile, "rgb:-";
push @$data, $rgb while (read IDATA,$rgb,3,0) == 3; push @$data, $rgb while (read IDATA,$rgb,3,0) == 3;
close IDATA; close IDATA;
# Check we have the right amount of data. # Check we have the right amount of data.
@ -82,7 +82,7 @@ $oh = $yend - $ystart + 1;
die "internal computation problem" if $ow != $oh; # should be square die "internal computation problem" if $ow != $oh; # should be square
# Now write out the resulting image, and resize it appropriately. # 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"; open IDATA, "|-", $convert, "-size", "${ow}x${oh}", "-depth", "8", "-resize", "${osize}x${osize}!", "rgb:-", $outfile;
for ($y = $ystart; $y <= $yend; $y++) { for ($y = $ystart; $y <= $yend; $y++) {
for ($x = $xstart; $x <= $xend; $x++) { for ($x = $xstart; $x <= $xend; $x++) {
if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) { if ($x >= 0 && $x < $w && $y >= 0 && $y < $h) {

View File

@ -1,19 +0,0 @@
# -*- makefile -*-
inertia : [X] GTK COMMON inertia inertia-icon|no-icon
inertia : [G] WINDOWS COMMON inertia inertia.res|noicon.res
ALL += inertia[COMBINED]
!begin am gtk
GAMES += inertia
!end
!begin >list.c
A(inertia) \
!end
!begin >gamedesc.txt
inertia:inertia.exe:Inertia:Gem-collecting puzzle:Collect all the gems without running into any of the mines.
!end

25
keen.R
View File

@ -1,25 +0,0 @@
# -*- makefile -*-
KEEN_EXTRA = dsf LATIN
KEEN_EXTRA_SOLVER = dsf LATIN_SOLVER
keen : [X] GTK COMMON keen KEEN_EXTRA keen-icon|no-icon
keen : [G] WINDOWS COMMON keen KEEN_EXTRA keen.res|noicon.res
keensolver : [U] keen[STANDALONE_SOLVER] KEEN_EXTRA_SOLVER STANDALONE
keensolver : [C] keen[STANDALONE_SOLVER] KEEN_EXTRA_SOLVER STANDALONE
ALL += keen[COMBINED] KEEN_EXTRA
!begin am gtk
GAMES += keen
!end
!begin >list.c
A(keen) \
!end
!begin >gamedesc.txt
keen:keen.exe:Keen:Arithmetic Latin square puzzle:Complete the latin square in accordance with the arithmetic clues.
!end

View File

@ -1,24 +0,0 @@
# -*- makefile -*-
LIGHTUP_EXTRA = combi
lightup : [X] GTK COMMON lightup LIGHTUP_EXTRA lightup-icon|no-icon
lightup : [G] WINDOWS COMMON lightup LIGHTUP_EXTRA lightup.res|noicon.res
lightupsolver : [U] lightup[STANDALONE_SOLVER] LIGHTUP_EXTRA STANDALONE
lightupsolver : [C] lightup[STANDALONE_SOLVER] LIGHTUP_EXTRA STANDALONE
ALL += lightup[COMBINED] LIGHTUP_EXTRA
!begin am gtk
GAMES += lightup
!end
!begin >list.c
A(lightup) \
!end
!begin >gamedesc.txt
lightup:lightup.exe:Light Up:Light-bulb placing puzzle:Place bulbs to light up all the squares.
!end

21
list.c Normal file
View File

@ -0,0 +1,21 @@
/*
* list.c: List of pointers to puzzle structures, for monolithic
* platforms.
*
* This file depends on the header "generated-games.h", which is
* constructed by CMakeLists.txt.
*/
#include "puzzles.h"
#define GAME(x) extern const game x;
#include "generated-games.h"
#undef GAME
#define GAME(x) &x,
const game *gamelist[] = {
#include "generated-games.h"
};
#undef GAME
const int gamecount = lenof(gamelist);

31
loopy.R
View File

@ -1,31 +0,0 @@
# -*- makefile -*-
LOOPY_EXTRA = tree234 dsf grid penrose loopgen
loopy : [X] GTK COMMON loopy LOOPY_EXTRA loopy-icon|no-icon
loopy : [G] WINDOWS COMMON loopy LOOPY_EXTRA loopy.res|noicon.res
loopysolver : [U] loopy[STANDALONE_SOLVER] LOOPY_EXTRA STANDALONE m.lib
loopysolver : [C] loopy[STANDALONE_SOLVER] LOOPY_EXTRA STANDALONE
#penrose : [U] penrose[TEST_PENROSE] STANDALONE m.lib
#penrose : [C] penrose[TEST_PENROSE] STANDALONE
#test-basis : [U] penrose[TEST_VECTORS] tree234 STANDALONE m.lib
#test-basis : [C] penrose[TEST_VECTORS] tree234 STANDALONE
ALL += loopy[COMBINED] LOOPY_EXTRA
!begin am gtk
GAMES += loopy
!end
!begin >list.c
A(loopy) \
!end
!begin >gamedesc.txt
loopy:loopy.exe:Loopy:Loop-drawing puzzle:Draw a single closed loop, given clues about number of adjacent edges.
!end

View File

@ -1,24 +0,0 @@
# -*- makefile -*-
MAGNETS_EXTRA = laydomino
magnets : [X] GTK COMMON magnets MAGNETS_EXTRA magnets-icon|no-icon
magnets : [G] WINDOWS COMMON magnets MAGNETS_EXTRA magnets.res|noicon.res
magnetssolver : [U] magnets[STANDALONE_SOLVER] MAGNETS_EXTRA STANDALONE m.lib
magnetssolver : [C] magnets[STANDALONE_SOLVER] MAGNETS_EXTRA STANDALONE
ALL += magnets[COMBINED] MAGNETS_EXTRA
!begin am gtk
GAMES += magnets
!end
!begin >list.c
A(magnets) \
!end
!begin >gamedesc.txt
magnets:magnets.exe:Magnets:Magnet-placing puzzle:Place magnets to satisfy the clues and avoid like poles touching.
!end

View File

@ -1,47 +0,0 @@
#!/bin/sh
# Build a Unix source distribution from the Puzzles SVN area.
#
# Pass a version number argument to have the archive tagged with that
# version number. Otherwise, the script will not version-tag the
# archive at all.
version="$1"
if test "x$version" != "x"; then
arcsuffix="-$version"
ver="-DVER=$version"
else
arcsuffix=
ver=
fi
perl mkfiles.pl
./mkauto.sh
mkdir tmp.$$
mkdir tmp.$$/puzzles$arcsuffix
mkdir tmp.$$/puzzles$arcsuffix/icons
# Build Windows Help and text versions of the manual for convenience.
halibut --winhelp=puzzles.hlp --text=puzzles.txt puzzles.but
# Build a text version of the HACKING document.
halibut --text=HACKING devel.but
for i in *.c *.m *.h *.R *.rc *.but *.plist *.icns LICENCE README Recipe \
*.rc2 mkfiles.pl Makefile Makefile.* \
HACKING puzzles.txt puzzles.hlp puzzles.cnt puzzles.chm \
icons/Makefile icons/*.sav icons/*.pl icons/*.sh icons/win16pal.xpm \
icons/*.png icons/*.ico icons/*.rc icons/*.c \
configure.ac mkauto.sh aclocal.m4 \
configure depcomp install-sh missing compile; do
case $i in
*/*) ln -s ../../../$i tmp.$$/puzzles$arcsuffix/$i;;
*) ln -s ../../$i tmp.$$/puzzles$arcsuffix/$i;;
esac
done
tar -C tmp.$$ -chzf - puzzles$arcsuffix > ../puzzles$arcsuffix.tar.gz
rm -rf tmp.$$

24
map.R
View File

@ -1,24 +0,0 @@
# -*- makefile -*-
MAP_EXTRA = dsf
map : [X] GTK COMMON map MAP_EXTRA map-icon|no-icon
map : [G] WINDOWS COMMON map MAP_EXTRA map.res|noicon.res
mapsolver : [U] map[STANDALONE_SOLVER] MAP_EXTRA STANDALONE m.lib
mapsolver : [C] map[STANDALONE_SOLVER] MAP_EXTRA STANDALONE
ALL += map[COMBINED] MAP_EXTRA
!begin am gtk
GAMES += map
!end
!begin >list.c
A(map) \
!end
!begin >gamedesc.txt
map:map.exe:Map:Map-colouring puzzle:Colour the map so that adjacent regions are never the same colour.
!end

24
mines.R
View File

@ -1,24 +0,0 @@
# -*- makefile -*-
MINES_EXTRA = tree234
mines : [X] GTK COMMON mines MINES_EXTRA mines-icon|no-icon
mines : [G] WINDOWS COMMON mines MINES_EXTRA mines.res|noicon.res
mineobfusc : [U] mines[STANDALONE_OBFUSCATOR] MINES_EXTRA STANDALONE
mineobfusc : [C] mines[STANDALONE_OBFUSCATOR] MINES_EXTRA STANDALONE
ALL += mines[COMBINED] MINES_EXTRA
!begin am gtk
GAMES += mines
!end
!begin >list.c
A(mines) \
!end
!begin >gamedesc.txt
mines:mines.exe:Mines:Mine-finding puzzle:Find all the mines without treading on any of them.
!end

View File

@ -1,2 +0,0 @@
#! /bin/sh
autoreconf -i && rm -rf autom4te.cache

1953
mkfiles.pl

File diff suppressed because it is too large Load Diff

23
net.R
View File

@ -1,23 +0,0 @@
# -*- makefile -*-
NET_EXTRA = tree234 dsf findloop
net : [X] GTK COMMON net NET_EXTRA net-icon|no-icon
# 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 NET_EXTRA net.res|noicon.res
ALL += net[COMBINED] NET_EXTRA
!begin am gtk
GAMES += net
!end
!begin >list.c
A(net) \
!end
!begin >gamedesc.txt
net:netgame.exe:Net:Network jigsaw puzzle:Rotate each tile to reassemble the network.
!end

View File

@ -1,21 +0,0 @@
# -*- makefile -*-
NETSLIDE_EXTRA = tree234
netslide : [X] GTK COMMON netslide NETSLIDE_EXTRA netslide-icon|no-icon
netslide : [G] WINDOWS COMMON netslide NETSLIDE_EXTRA netslide.res|noicon.res
ALL += netslide[COMBINED] NETSLIDE_EXTRA
!begin am gtk
GAMES += netslide
!end
!begin >list.c
A(netslide) \
!end
!begin >gamedesc.txt
netslide:netslide.exe:Netslide:Toroidal sliding network puzzle:Slide a row at a time to reassemble the network.
!end

View File

@ -1,11 +0,0 @@
/* Puzzle resource file without an icon, used in the absence of icons/foo.rc */
#include "puzzles.rc2"
/* XXX this probably isn't the right test, but it'll do. */
#ifdef MINGW32_FIX
/* XXX The MinGW toolchain (specifically, windres) doesn't like a resource
* file with no resources. Give it a dummy one.
* This can go if/when VERSIONINFO resources are added. */
200 RCDATA { 0 }
#endif

View File

@ -1,12 +0,0 @@
# -*- 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-icon|no-icon
nullgame : [G] WINDOWS COMMON nullgame nullgame.res|noicon.res

4
osx.m
View File

@ -77,7 +77,9 @@
* recreate it. * recreate it.
*/ */
#define COMBINED /* we put all the puzzles in one binary in this port */ #ifndef COMBINED
#error Expected -DCOMBINED to come from the makefile
#endif
#include <ctype.h> #include <ctype.h>
#include <time.h> #include <time.h>

View File

@ -1,21 +0,0 @@
# -*- makefile -*-
PALISADE_EXTRA = divvy dsf
palisade : [X] GTK COMMON palisade PALISADE_EXTRA palisade-icon|no-icon
palisade : [G] WINDOWS COMMON palisade PALISADE_EXTRA palisade.res|noicon.res
ALL += palisade[COMBINED] PALISADE_EXTRA
!begin am gtk
GAMES += palisade
!end
!begin >list.c
A(palisade) \
!end
!begin >gamedesc.txt
palisade:palisade.exe:Palisade:Grid-division puzzle:Divide the grid into equal-sized areas in accordance with the clues.
!end

View File

@ -1,25 +0,0 @@
# -*- makefile -*-
pattern : [X] GTK COMMON pattern pattern-icon|no-icon
pattern : [G] WINDOWS COMMON pattern pattern.res|noicon.res
patternsolver : [U] pattern[STANDALONE_SOLVER] STANDALONE
patternsolver : [C] pattern[STANDALONE_SOLVER] STANDALONE
patternpicture : [U] pattern[STANDALONE_PICTURE_GENERATOR] STANDALONE
patternpicture : [C] pattern[STANDALONE_PICTURE_GENERATOR] STANDALONE
ALL += pattern[COMBINED]
!begin am gtk
GAMES += pattern
!end
!begin >list.c
A(pattern) \
!end
!begin >gamedesc.txt
pattern:pattern.exe:Pattern:Pattern puzzle:Fill in the pattern in the grid, given only the lengths of runs of black squares.
!end

23
pearl.R
View File

@ -1,23 +0,0 @@
# -*- makefile -*-
PEARL_EXTRA = dsf tree234 grid penrose loopgen tdq
pearl : [X] GTK COMMON pearl PEARL_EXTRA pearl-icon|no-icon
pearl : [G] WINDOWS COMMON pearl PEARL_EXTRA pearl.res?
pearlbench : [U] pearl[STANDALONE_SOLVER] PEARL_EXTRA STANDALONE m.lib
pearlbench : [C] pearl[STANDALONE_SOLVER] PEARL_EXTRA STANDALONE
ALL += pearl[COMBINED] PEARL_EXTRA
!begin am gtk
GAMES += pearl
!end
!begin >list.c
A(pearl) \
!end
!begin >gamedesc.txt
pearl:pearl.exe:Pearl:Loop-drawing puzzle:Draw a single closed loop, given clues about corner and straight squares.
!end

21
pegs.R
View File

@ -1,21 +0,0 @@
# -*- makefile -*-
PEGS_EXTRA = tree234
pegs : [X] GTK COMMON pegs PEGS_EXTRA pegs-icon|no-icon
pegs : [G] WINDOWS COMMON pegs PEGS_EXTRA pegs.res|noicon.res
ALL += pegs[COMBINED] PEGS_EXTRA
!begin am gtk
GAMES += pegs
!end
!begin >list.c
A(pegs) \
!end
!begin >gamedesc.txt
pegs:pegs.exe:Pegs:Peg solitaire puzzle:Jump pegs over each other to remove all but one.
!end

View File

@ -1,4 +1,15 @@
/* Standard stuff that goes into the Windows resources for all puzzles. */ /* Windows resource file for all puzzles. */
#if defined ICON_FILE
200 ICON ICON_FILE
#else
#ifdef MINGW32_FIX
/* XXX The MinGW toolchain (specifically, windres) doesn't like a resource
* file with no resources. Give it a dummy one.
* This can go if/when VERSIONINFO resources are added. */
200 RCDATA { 0 }
#endif
#endif
#ifdef _WIN32_WCE #ifdef _WIN32_WCE

21
range.R
View File

@ -1,21 +0,0 @@
# -*- makefile -*-
RANGE_EXTRA = dsf
range : [X] GTK COMMON range RANGE_EXTRA range-icon|no-icon
range : [G] WINDOWS COMMON range RANGE_EXTRA range.res|noicon.res
ALL += range[COMBINED] RANGE_EXTRA
!begin am gtk
GAMES += range
!end
!begin >list.c
A(range) \
!end
!begin >gamedesc.txt
range:range.exe:Range:Visible-distance puzzle:Place black squares to limit the visible distance from each numbered cell.
!end

19
rect.R
View File

@ -1,19 +0,0 @@
# -*- makefile -*-
rect : [X] GTK COMMON rect rect-icon|no-icon
rect : [G] WINDOWS COMMON rect rect.res|noicon.res
ALL += rect[COMBINED]
!begin am gtk
GAMES += rect
!end
!begin >list.c
A(rect) \
!end
!begin >gamedesc.txt
rect:rect.exe:Rectangles:Rectangles puzzle:Divide the grid into rectangles with areas equal to the numbers.
!end

View File

@ -1,19 +0,0 @@
# -*- makefile -*-
samegame : [X] GTK COMMON samegame samegame-icon|no-icon
samegame : [G] WINDOWS COMMON samegame samegame.res|noicon.res
ALL += samegame[COMBINED]
!begin am gtk
GAMES += samegame
!end
!begin >list.c
A(samegame) \
!end
!begin >gamedesc.txt
samegame:samegame.exe:Same Game:Block-clearing puzzle:Clear the grid by removing touching groups of the same colour squares.
!end

View File

@ -1,23 +0,0 @@
# -*- makefile -*-
SIGNPOST_EXTRA = dsf
signpost : [X] GTK COMMON signpost SIGNPOST_EXTRA signpost-icon|no-icon
signpost : [G] WINDOWS COMMON signpost SIGNPOST_EXTRA signpost.res|noicon.res
signpostsolver : [U] signpost[STANDALONE_SOLVER] SIGNPOST_EXTRA STANDALONE m.lib
signpostsolver : [C] signpost[STANDALONE_SOLVER] SIGNPOST_EXTRA STANDALONE
ALL += signpost[COMBINED] SIGNPOST_EXTRA
!begin am gtk
GAMES += signpost
!end
!begin >list.c
A(signpost) \
!end
!begin >gamedesc.txt
signpost:signpost.exe:Signpost:Square-connecting puzzle:Connect the squares into a path following the arrows.
!end

View File

@ -1,23 +0,0 @@
# -*- makefile -*-
SINGLES_EXTRA = dsf LATIN
singles : [X] GTK COMMON singles SINGLES_EXTRA singles-icon|no-icon
singles : [G] WINDOWS COMMON singles SINGLES_EXTRA singles.res|noicon.res
ALL += singles[COMBINED] SINGLES_EXTRA
singlessolver : [U] singles[STANDALONE_SOLVER] SINGLES_EXTRA STANDALONE
singlessolver : [C] singles[STANDALONE_SOLVER] SINGLES_EXTRA STANDALONE
!begin am gtk
GAMES += singles
!end
!begin >list.c
A(singles) \
!end
!begin >gamedesc.txt
singles:singles.exe:Singles:Number-removing puzzle:Black out the right set of duplicate numbers.
!end

View File

@ -1,19 +0,0 @@
# -*- makefile -*-
sixteen : [X] GTK COMMON sixteen sixteen-icon|no-icon
sixteen : [G] WINDOWS COMMON sixteen sixteen.res|noicon.res
ALL += sixteen[COMBINED]
!begin am gtk
GAMES += sixteen
!end
!begin >list.c
A(sixteen) \
!end
!begin >gamedesc.txt
sixteen:sixteen.exe:Sixteen:Toroidal sliding block puzzle:Slide a row at a time to arrange the tiles into order.
!end

24
slant.R
View File

@ -1,24 +0,0 @@
# -*- makefile -*-
SLANT_EXTRA = dsf findloop
slant : [X] GTK COMMON slant SLANT_EXTRA slant-icon|no-icon
slant : [G] WINDOWS COMMON slant SLANT_EXTRA slant.res|noicon.res
slantsolver : [U] slant[STANDALONE_SOLVER] SLANT_EXTRA STANDALONE
slantsolver : [C] slant[STANDALONE_SOLVER] SLANT_EXTRA STANDALONE
ALL += slant[COMBINED] SLANT_EXTRA
!begin am gtk
GAMES += slant
!end
!begin >list.c
A(slant) \
!end
!begin >gamedesc.txt
slant:slant.exe:Slant:Maze-drawing puzzle:Draw a maze of slanting lines that matches the clues.
!end

24
solo.R
View File

@ -1,24 +0,0 @@
# -*- makefile -*-
SOLO_EXTRA = divvy dsf
solo : [X] GTK COMMON solo SOLO_EXTRA solo-icon|no-icon
solo : [G] WINDOWS COMMON solo SOLO_EXTRA solo.res|noicon.res
solosolver : [U] solo[STANDALONE_SOLVER] SOLO_EXTRA STANDALONE
solosolver : [C] solo[STANDALONE_SOLVER] SOLO_EXTRA STANDALONE
ALL += solo[COMBINED] SOLO_EXTRA
!begin am gtk
GAMES += solo
!end
!begin >list.c
A(solo) \
!end
!begin >gamedesc.txt
solo:solo.exe:Solo:Number placement puzzle:Fill in the grid so that each row, column and square block contains one of every digit.
!end

24
tents.R
View File

@ -1,24 +0,0 @@
# -*- makefile -*-
TENTS_EXTRA = matching dsf
tents : [X] GTK COMMON tents TENTS_EXTRA tents-icon|no-icon
tents : [G] WINDOWS COMMON tents TENTS_EXTRA tents.res|noicon.res
ALL += tents[COMBINED] TENTS_EXTRA
tentssolver : [U] tents[STANDALONE_SOLVER] TENTS_EXTRA STANDALONE
tentssolver : [C] tents[STANDALONE_SOLVER] TENTS_EXTRA STANDALONE
!begin am gtk
GAMES += tents
!end
!begin >list.c
A(tents) \
!end
!begin >gamedesc.txt
tents:tents.exe:Tents:Tent-placing puzzle:Place a tent next to each tree.
!end

View File

@ -1,25 +0,0 @@
# -*- makefile -*-
TOWERS_EXTRA = LATIN
TOWERS_EXTRA_SOLVER = LATIN_SOLVER
towers : [X] GTK COMMON towers TOWERS_EXTRA towers-icon|no-icon
towers : [G] WINDOWS COMMON towers TOWERS_EXTRA towers.res|noicon.res
towerssolver : [U] towers[STANDALONE_SOLVER] TOWERS_EXTRA_SOLVER STANDALONE
towerssolver : [C] towers[STANDALONE_SOLVER] TOWERS_EXTRA_SOLVER STANDALONE
ALL += towers[COMBINED] TOWERS_EXTRA
!begin am gtk
GAMES += towers
!end
!begin >list.c
A(towers) \
!end
!begin >gamedesc.txt
towers:towers.exe:Towers:Tower-placing Latin square puzzle:Complete the latin square of towers in accordance with the clues.
!end

View File

@ -1,24 +0,0 @@
# -*- makefile -*-
TRACKS_EXTRA = dsf findloop
tracks : [X] GTK COMMON tracks TRACKS_EXTRA tracks-icon|no-icon
tracks : [G] WINDOWS COMMON tracks TRACKS_EXTRA tracks.res|noicon.res
ALL += tracks[COMBINED] TRACKS_EXTRA
trackssolver : [U] tracks[STANDALONE_SOLVER] TRACKS_EXTRA STANDALONE
trackssolver : [C] tracks[STANDALONE_SOLVER] TRACKS_EXTRA STANDALONE
!begin am gtk
GAMES += tracks
!end
!begin >list.c
A(tracks) \
!end
!begin >gamedesc.txt
tracks:tracks.exe:Tracks:Path-finding railway track puzzle:Fill in the railway track according to the clues.
!end

View File

@ -1,19 +0,0 @@
# -*- makefile -*-
twiddle : [X] GTK COMMON twiddle twiddle-icon|no-icon
twiddle : [G] WINDOWS COMMON twiddle twiddle.res|noicon.res
ALL += twiddle[COMBINED]
!begin am gtk
GAMES += twiddle
!end
!begin >list.c
A(twiddle) \
!end
!begin >gamedesc.txt
twiddle:twiddle.exe:Twiddle:Rotational sliding block puzzle:Rotate the tiles around themselves to arrange them into order.
!end

View File

@ -1,18 +0,0 @@
# -*- makefile -*-
undead : [X] GTK COMMON undead undead-icon|no-icon
undead : [G] WINDOWS COMMON undead undead.res|noicon.res
ALL += undead[COMBINED]
!begin am gtk
GAMES += undead
!end
!begin >list.c
A(undead) \
!end
!begin >gamedesc.txt
undead:undead.exe:Undead:Monster-placing puzzle:Place ghosts, vampires and zombies so that the right numbers of them can be seen in mirrors.
!end

View File

@ -1,25 +0,0 @@
# -*- makefile -*-
UNEQUAL_EXTRA = LATIN
UNEQUAL_EXTRA_SOLVER = LATIN_SOLVER
unequal : [X] GTK COMMON unequal UNEQUAL_EXTRA unequal-icon|no-icon
unequal : [G] WINDOWS COMMON unequal UNEQUAL_EXTRA unequal.res|noicon.res
unequalsolver : [U] unequal[STANDALONE_SOLVER] UNEQUAL_EXTRA_SOLVER STANDALONE
unequalsolver : [C] unequal[STANDALONE_SOLVER] UNEQUAL_EXTRA_SOLVER STANDALONE
ALL += unequal[COMBINED] UNEQUAL_EXTRA
!begin am gtk
GAMES += unequal
!end
!begin >list.c
A(unequal) \
!end
!begin >gamedesc.txt
unequal:unequal.exe:Unequal:Latin square puzzle:Complete the latin square in accordance with the > signs.
!end

31
unfinished/CMakeLists.txt Normal file
View File

@ -0,0 +1,31 @@
puzzle(group
DISPLAYNAME "Group"
DESCRIPTION "Group theory puzzle"
OBJECTIVE "Complete the unfinished Cayley table of a group.")
solver(group ${CMAKE_SOURCE_DIR}/latin.c)
puzzle(separate
DISPLAYNAME "Separate"
DESCRIPTION "Rectangle-dividing puzzle"
OBJECTIVE "Partition the grid into regions containing one of each letter.")
puzzle(slide
DISPLAYNAME "Slide"
DESCRIPTION "Sliding block puzzle"
OBJECTIVE "Slide the blocks to let the key block out.")
solver(slide)
puzzle(sokoban
DISPLAYNAME "Sokoban"
DESCRIPTION "Barrel-pushing puzzle"
OBJECTIVE "Push all the barrels into the target squares.")
# These unfinished programs don't even have the structure of a puzzle
# game yet; they're just command-line programs containing test
# implementations of some of the needed functionality.
cliprogram(numgame numgame.c)
cliprogram(path path.c COMPILE_DEFINITIONS TEST_GEN)
export_variables_to_parent_scope()

View File

@ -2,8 +2,13 @@ This subdirectory contains puzzle implementations which are
half-written, fundamentally flawed, or in other ways unready to be half-written, fundamentally flawed, or in other ways unready to be
shipped as part of the polished Puzzles collection. shipped as part of the polished Puzzles collection.
Those puzzles which have .R files can be built as part of the The CMake build system will _build_ all of the source in this
Puzzles collection by symlinking their source files into the parent directory (to ensure it hasn't become unbuildable), but they won't be
directory and re-running mkfiles.pl. Anything without a .R file included in all-in-one puzzle binaries or installed by 'make install'
isn't even finished enough to do that, and you should read the targets. If you want to temporarily change that, you can reconfigure
source file itself to find out the status. your build by defining the CMake variable PUZZLES_ENABLE_UNFINISHED.
For example,
cmake . -DPUZZLES_ENABLE_UNFINISHED="group;slide"
will build as if both Group and Slide were fully official puzzles.

View File

@ -1,25 +0,0 @@
# -*- makefile -*-
GROUP_EXTRA = LATIN
GROUP_EXTRA_SOLVER = LATIN_SOLVER
group : [X] GTK COMMON group GROUP_EXTRA group-icon|no-icon
group : [G] WINDOWS COMMON group GROUP_EXTRA group.res|noicon.res
groupsolver : [U] group[STANDALONE_SOLVER] GROUP_EXTRA_SOLVER STANDALONE
groupsolver : [C] group[STANDALONE_SOLVER] GROUP_EXTRA_SOLVER STANDALONE
ALL += group[COMBINED] GROUP_EXTRA
!begin am gtk
GAMES += group
!end
!begin >list.c
A(group) \
!end
!begin >gamedesc.txt
group:group.exe:Group:Group theory puzzle:Complete the unfinished Cayley table of a group.
!end

View File

@ -1,21 +0,0 @@
# -*- makefile -*-
SEPARATE_EXTRA = divvy dsf
separate : [X] GTK COMMON separate SEPARATE_EXTRA separate-icon|no-icon
separate : [G] WINDOWS COMMON separate SEPARATE_EXTRA separate.res|noicon.res
ALL += separate[COMBINED] SEPARATE_EXTRA
!begin am gtk
GAMES += separate
!end
!begin >list.c
A(separate) \
!end
!begin >gamedesc.txt
separate:separate.exe:Separate:Rectangle-dividing puzzle:Partition the grid into regions containing one of each letter.
!end

View File

@ -1,24 +0,0 @@
# -*- makefile -*-
SLIDE_EXTRA = dsf tree234
slide : [X] GTK COMMON slide SLIDE_EXTRA slide-icon|no-icon
slide : [G] WINDOWS COMMON slide SLIDE_EXTRA slide.res|noicon.res
slidesolver : [U] slide[STANDALONE_SOLVER] SLIDE_EXTRA STANDALONE
slidesolver : [C] slide[STANDALONE_SOLVER] SLIDE_EXTRA STANDALONE
ALL += slide[COMBINED] SLIDE_EXTRA
!begin am gtk
GAMES += slide
!end
!begin >list.c
A(slide) \
!end
!begin >gamedesc.txt
slide:slide.exe:Slide:Sliding block puzzle:Slide the blocks to let the key block out.
!end

View File

@ -1,19 +0,0 @@
# -*- makefile -*-
sokoban : [X] GTK COMMON sokoban sokoban-icon|no-icon
sokoban : [G] WINDOWS COMMON sokoban sokoban.res?
ALL += sokoban[COMBINED]
!begin am gtk
GAMES += sokoban
!end
!begin >list.c
A(sokoban) \
!end
!begin >gamedesc.txt
sokoban:sokoban.exe:Sokoban:Barrel-pushing puzzle:Push all the barrels into the target squares.
!end

View File

@ -1,21 +0,0 @@
# -*- makefile -*-
unruly : [X] GTK COMMON unruly unruly-icon|no-icon
unruly : [G] WINDOWS COMMON unruly unruly.res|noicon.res
unrulysolver : [U] unruly[STANDALONE_SOLVER] STANDALONE
unrulysolver : [C] unruly[STANDALONE_SOLVER] STANDALONE
ALL += unruly[COMBINED]
!begin am gtk
GAMES += unruly
!end
!begin >list.c
A(unruly) \
!end
!begin >gamedesc.txt
unruly:unruly.exe:Unruly:Black and white grid puzzle:Fill in the black and white grid to avoid runs of three.
!end

View File

@ -1,21 +0,0 @@
# -*- makefile -*-
UNTANGLE_EXTRA = tree234
untangle : [X] GTK COMMON untangle UNTANGLE_EXTRA untangle-icon|no-icon
untangle : [G] WINDOWS COMMON untangle UNTANGLE_EXTRA untangle.res|noicon.res
ALL += untangle[COMBINED] UNTANGLE_EXTRA
!begin am gtk
GAMES += untangle
!end
!begin >list.c
A(untangle) \
!end
!begin >gamedesc.txt
untangle:untangle.exe:Untangle:Planar graph layout puzzle:Reposition the points so that the lines do not cross.
!end

View File

@ -9,8 +9,10 @@ use strict;
use warnings; use warnings;
use HTML::Entities; use HTML::Entities;
open my $desc, "<", "gamedesc.txt" my $gamedesc = shift @ARGV;
or die "gamedesc.txt: open: $!\n";
open my $desc, "<", $gamedesc
or die "$gamedesc: open: $!\n";
open my $spans, ">", "wwwspans.html" open my $spans, ">", "wwwspans.html"
or die "wwwspans.html: open: $!\n"; or die "wwwspans.html: open: $!\n";