26 Commits

Author SHA1 Message Date
f63810fbc8 Don't use Null Game's extra source files for all GUI programs
All the not-quite-puzzle GUI programs (only galaxieseditor at this
point) were using the extra source files from Null Game, presumably as a
convenient way of asking not to have an icon on platforms where icons
are provided as extra source files.  Unfortunately, this all went wrong
if Null Game did have a save file for an icon, causing CMake to complain
about multiple definitions of a target.

Now these programs look for extra files under their own names, which
will work just as well since those have no save files to generate icons
from either.
2022-12-31 16:18:53 +00:00
00e4d79db1 js: Enable STRICT_JS in Emscripten
This turns on "use strict" in JavaScript, which enforces declaring
variables among other things, and may allow better optimisations.
2022-11-10 00:40:52 +00:00
fa58dd85b7 js: Distinguish manual resizes from device pixel ratio changes
This adds a new callback, rescale_puzzle(), that's called when the
device pixel ratio changes.  This means that resize_puzzle() can safely
set the nominal canvas size, which means that manual resizing of the
puzzle now sticks.

Still missing: paying attention to the device pixel ratio when choosing
the initial (or reset) size.
2022-10-27 22:51:54 +01:00
5af0cd4ac1 js: Add a CMake variable to control whether Emscripten emits WASM
I've finally got bored of keeping (and occasionally losing) a patch
that turns it off unconditionally.
2022-10-27 09:59:04 +01:00
27dd36e3e6 Enable Apple Silicon in the MacOS builds. 2022-09-12 11:01:40 +01:00
9c13279938 unix, gtk: Install and use HTML help
- Generate HTML pages from the manual, and install them
- Add "Contents" and "Help on <name>" menu items that will open the
  appropriate page in a web browser
2022-08-01 18:41:10 +01:00
1600818848 Try to fix flakiness in the NestedVM build.
I've had a lot of Puzzles nightly builds fail recently in the NestedVM
stage, with a 'jar' command producing a message along these lines:

java.util.zip.ZipException: attempt to write past end of STORED entry
        at java.base/java.util.zip.ZipOutputStream.write(ZipOutputStream.java:337)
        at jdk.jartool/sun.tools.jar.Main.copy(Main.java:1250)
        at jdk.jartool/sun.tools.jar.Main.copy(Main.java:1263)
        at jdk.jartool/sun.tools.jar.Main.addFile(Main.java:1211)
        at jdk.jartool/sun.tools.jar.Main.create(Main.java:879)
        at jdk.jartool/sun.tools.jar.Main.run(Main.java:319)
        at jdk.jartool/sun.tools.jar.Main.main(Main.java:1681)
        Suppressed: java.util.zip.ZipException: invalid entry size (expected 0 but got 786 bytes)
                at java.base/java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:288)
                at java.base/java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:361)
                at java.base/java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:238)
                at java.base/java.util.zip.ZipOutputStream.close(ZipOutputStream.java:378)
                at jdk.jartool/sun.tools.jar.Main.create(Main.java:854)
                ... 2 more

It's hard to work out exactly what this error dump means, and
web-searching for the error message isn't much help because the same
exception can occur in application code using java.util.zip, and most
mentions on the web are about that, and not about what I want to know,
which is why it might happen in the 'jar' program in particular.

However, the clues visible in that message suggest that 'jar' had
somehow got confused about the size of one of the files it was adding
to the jar archive, in that it initially decided it was 0 bytes long
and later found it was longer. That suggests a problem of excessive
parallelism between the build steps, perhaps due to a missing
dependency in the makefile, which might plausibly cause the 'jar' step
to be running already while some file it needs to read is still being
written. (Which would also explain why it doesn't happen every time.)

An eyeball review of cmake/platforms/nestedvm.cmake didn't find any
obvious missing dependencies. But I vaguely remembered that in some
other context I'd had trouble with cmake 'add_custom_command'. So in
this commit I replace all those custom commands with custom _targets_,
listing the previous OUTPUT files as BYPRODUCTS. And then the
dependencies are written using the target names, instead of the file
names.

I don't fully understand why this should make a difference. But it
seems more reliable in a soak test, and still builds the right things,
so I'll commit it and see if it makes the flakiness in the actual
nightly builds stop happening.
2022-01-06 09:03:28 +00:00
57fbcd2b29 malloc.c: check allocation sizes against PTRDIFF_MAX.
I don't expect this to actually come up in any circumstance, but it
prevents a warning in some versions of gcc that would otherwise arise
from the use of 'int' to compute the input size: if gcc isn't
confident that the int is positive, then it complains that possible
inputs to malloc might be in the region of 2^64 - (small multiple of a
negative 32-bit int).

I would hope malloc would fail in any case on such an input, so
failing a couple of lines earlier makes no important difference.

Annoyingly, stdint.h is missing in my NestedVM build setup (though it
has stdbool.h - it's not _totally_ C90). So I have to check that at
cmake time.

Also, removed the #defines for smalloc and friends from the tree234
test mode. These were needed in the old build system, when
tree234-test was built ad-hoc without being linked against malloc.c.
But now tree234-test links against the same utils library as
everything else, and can use the real smalloc - and doing so prevents
another of these warnings when compiling with -flto.
2021-12-11 11:59:25 +00:00
6691ad180c Fix benchmark.sh for the new cmake world.
It relied on reading gamedesc.txt to find a list of puzzle binaries to
run. But gamedesc.txt is now specific to the Windows build (since it
contains Windows executable names), and isn't available in the Unix
cmake build directory.

Fixed by making a simpler gamelist.txt available on all platforms.
2021-09-06 10:57:40 +01:00
d5b53853aa Permit building GUI helper tools.
These look like puzzles, in that they link against a frontend and
provide the usual 'struct game', but they don't count as a puzzle for
purposes of shipping, or even having to have descriptions and icons.

There's one of these buried in the code already under an ifdef, which
I'll re-enable in the next commit.
2021-05-25 10:45:40 +01:00
806e4e4088 nestedvm.cmake: fix accidental use of dynamic scope.
In this platform's set_platform_puzzle_target_properties, I referred
to ${EXENAME} twice, which is not one of the function parameters. It
worked anyway, because CMake has dynamic scope, and that variable was
defined - to the right value - within the local-variable scope of the
calling function. But that wasn't at all what I meant to do!

Renamed it to ${TARGET}, which is the actual parameter name we get
passed.
2021-05-25 10:44:28 +01:00
8ff394d1cc Toolchain file for MinGW cross-compilation.
Cribbed from the PuTTY one. Use with something like
cmake . -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw.cmake
2021-04-27 11:06:44 +01:00
77866e1335 wasm/js/emscripten: Fix page loading race
Using a stunt webserver which artificially introduces a 3s delay just
before the last line of the HTML output, I have reproduced a
uwer-reported loading/startup race bug:

Previously the wasm loading was started by the <script> element,
synchronously. If the wasm loading is fast, and finishes before the
HTML loading, the onRuntimeInitialized event may occur before
initPuzzles.  But initPuzzles sets up the event handler.

Fix this bug, and introduce a new comment containing an argument for
the correctness of the new approach.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
2021-04-22 21:22:48 +01:00
3cf0a3b7b0 Suppress too-noisy Visual Studio warnings.
With this and the previous commit's fix for real problems, the Puzzles
build on VS is now warning-free.
2021-04-19 18:12:36 +01:00
8fa545c76c Set ALLOW_MEMORY_GROWTH in the Emscripten build.
How embarrassing. When I updated the Emscripten build to use WASM, a
major reason I bothered to do it at all was that I'd heard that WASM
was capable of reallocating its memory arena larger on the fly. Turns
out that it _can_, but only if you specifically set the option in
Emscripten to allow it.

With this option set, I can finish a 25x25 Galaxies, where previously
the game would crash part way through (and not even a very large part)
with errors about memory growth in the Javascript console.
2021-04-16 18:07:15 +01:00
8c97ef434f Stop advertising GTK 1 as an option!
When I wrote yesterday's commit c0c64dc1051bcbd I momentarily forgot
which of my projects still support GTK 1 and which don't. Puzzles
doesn't.
2021-04-05 11:00:05 +01:00
c0c64dc105 Advertise user-configurable cmake-time config options.
Various cmake variables that I was informally expecting users to set
on the cmake command line (e.g. cmake -DSTRICT=ON, or cmake
-DPUZZLES_GTK_VERSION=2) are now labelled explicitly with the CACHE
tag, and provided with a documentation string indicating what they're
for.

One effect of this is that GUI-like interfaces to your cmake build
directory, such as ccmake or cmake-gui, will show those variables
explicitly to give you a hint that you might want to change them.

Another is that when you do change them, cmake will recognise that it
needs to redo the rest of its configuration. Previously, if you sat in
an existing cmake build directory and did 'cmake -DSTRICT=ON .'
followed by 'cmake -DSTRICT=OFF .', nothing would happen, even though
you obviously meant it to.
2021-04-04 14:58:39 +01:00
b685eee478 Install desktop files and pixmaps from CMake 2021-04-03 10:35:14 +01:00
f6434e8496 Update web puzzles to current WASM-based Emscripten.
I presume this will improve performance. Also, if I've understood
correctly, WASM-based compiled web code is capable of automatically
growing its memory, which the previous asm.js build of the puzzles
could not do, and occasionally caused people to complain that if they
tried to play a _really big_ game in their browser, the JS would
eventually freeze because the emulated memory ran out.

I've been putting off doing this for ages because my previous
Emscripten build setup was so finicky that I didn't like to meddle
with it. But now that the new cmake system in this source tree makes
things generally easier, and particularly since I've just found out
that the up-to-date Emscripten is available as a Docker image (namely
"emscripten/emsdk"), this seemed like a good moment to give it a try.

The source and build changes required for this update weren't too
onerous. I was half expecting a huge API upheaval, and indeed there
was _some_ change, but very little:

 - in the JS initPuzzle function, move the call to Module.callMain()
   into Module.onRuntimeInitialized instead of doing it at the top
   level, because New Emscripten's .js output likes to load the
   accompanying .wasm file asynchronously, so you can't call the WASM
   main() until it actually exists.

 - in the JS-side library code, replace all uses of Emscripten's
   Pointer_stringify() function with the new name UTF8ToString(). (The
   new version also has an ASCIIToString(), so I guess the reason for
   the name change is that now you get to choose which character set
   you meant. I need to use UTF-8, so that the × and ÷ signs in Keen
   will work.)

 - set EXTRA_EXPORTED_RUNTIME_METHODS=[cwrap,callMain] on the emcc
   link command line, otherwise they aren't available for my JS setup
   code to call.

 - (removed -s ASM_JS=1 from the link options, though I'm not actually
   sure it made any difference one way or the other in the new WASM
   world)

 - be prepared for a set of .wasm files to show up as build products
   alongside the .js ones.

 - stop building with -DCMAKE_BUILD_TYPE=Release! I'm not sure why
   that was needed, but if I leave that flag on my cmake command line,
   the output .js file fails to embed my emccpre.js, so the initial
   call to initPuzzle() fails from the HTML wrapper page, meaning
   nothing at all happens.
2021-04-03 09:22:49 +01:00
e1b9047b55 emscripten.cmake: remove a rogue diagnostic.
I somehow left this in while I was trying to get the Emscripten cmake
build to work in the first place.
2021-04-03 08:44:22 +01:00
a1bab40025 Support earlier versions of CMake.
At least, for the Unix build, so as to support Debian stable and a
couple of prior Ubuntu LTSes.

Not much needed to change in the cmake scripts; the only noticeable
difference was that the 'install' command needs an explicit RUNTIME
DESTINATION.
2021-04-03 08:03:25 +01:00
e763b9ead8 Don't try to build the icons when cross-compiling.
The puzzle icons are built by compiling and running a preliminary
set of puzzle binaries. We can't do that if the binaries won't run
on the build host.
2021-04-01 17:55:21 +01:00
dd8164b774 Unix: allow adding a prefix to all the puzzle names.
A distro maintainer reminds me that downstreams often want to rename
my quite generic executable names to avoid clashes in bin directories.
Added a cmake option -DOUTPUT_NAME to make that easy.
2021-03-31 18:44:44 +01:00
306fab356e Stop automatically adding warning flags and -Werror.
It's better to be lax for normal users trying to build the puzzles
from source to actually run them. That way, warning changes in some
particular compiler I haven't seen yet won't break the build.

Instead, I've invented a cmake setting -DSTRICT=ON which turns on all
those flags. So I can build with them myself, to ensure the code is as
portable as possible. And that flag is set in Buildscr, so that my
official builds won't complete until that warning mode is satisfied.
2021-03-31 18:44:44 +01:00
76aa9619c0 Provide pre-built icons in the source tarball.
This reinstates the feature of the previous build system, that the C
icon files for the GTK puzzles were included in the source tarball, so
that users building from that instead of from the raw git repo would
not need to run the fiddly piece of build that regenerates them.

Running that fiddly piece of build is much easier in the CMake world
(because it's integrated with the main makefile), but it has a build
dependency on ImageMagick which is easily avoided.

The makefile will still build the icons if it _can_. But in the case
where it can't, it will use pre-built icon source files if they're
available, and only fall back to no-icon.c if it can't even do that.
(So a user checking out from git and building without ImageMagick
present will still be able to build _something_ playable.)
2021-03-31 18:44:44 +01:00
cc7f5503dc 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.
2021-03-29 19:02:23 +01:00