I've only just found out that it has the effect of treating the argv
words not as plain filenames, but as arguments to Perl default 'open',
i.e. if they end in | then the text before that is treated as a
command. That's not what was intended!
Thanks to Rocco Matano for reporting that in the -DCOMBINED version of
the Windows front end, switching games causes a crash because the
presets menu from the old midend is still left over in fe, and its
presence inhibits the setup code from making a new one. Now we throw
it out at the same time as we throw out the old midend itself.
Also, the condition 'if (!fe->preset_menu)' was misguided. I think the
point of that was to avoid pointlessly tearing down and rebuilding the
preset menu when we're _not_ changing game - but that's a cost too
small to worry about if it causes the slightest trouble. Now
fe->preset_menu should always be NULL at that point in the function,
so I've replaced the if with an assert.
Moving the snaffle_colours() call earlier is fine in GTK 3, where the
potential call to frontend_default_colour doesn't depend on the window
already having been created. But it falls over in GTK 2 where it does.
Moved the non-headless-mode version of that call back to where it was
before the --screenshot change.
I had this idea today and immediately wondered why I'd never had it
before!
To generate the puzzle screenshots used on the website and as program
icons, we run the GTK front end with the --screenshot option, which
sets up GTK, insists on connecting to an X server (or other display),
draws the state of a puzzle on a Cairo surface, writes that surface
out to a .png file, and exits.
But there's no reason we actually need the GTK setup during that
process, especially because the surface we do the drawing on is our
_own_ surface, not even one provided to us by GTK. We could just set
up a Cairo surface by itself, draw on it, and save it to a file.
Calling gtk_init is not only pointless, but actively inconvenient,
because it means the build script depends on having an X server
available for the sole purpose of making gtk_init not complain.
So now I've simplified things, by adding a 'headless' flag in
new_window and the frontend structure, which suppresses all uses of
actual GTK, leaving only the Cairo surface setup and enough supporting
stuff (like colours) to generate the puzzle image. One awkward build
dependency removed.
This means that --screenshot no longer works in GTK 2, which I don't
care about, because it only needs to run on _one_ platform.
Another thing I spotted while trawling the whole source base was that
a couple of games had omitted 'static' on a lot of their internal
functions. Checking with nm, there turned out to be quite a few more
than I'd spotted by eye, so this should fix them all.
Also added one missing 'const', on the lookup table nbits[] in Tracks.
I noticed this during the bool trawl: both of these games have an
array of flags indicating which grid squares are immutable starting
clues, and copy it in every call to dup_game, which is completely
unnecessary because it doesn't change during play. So now each one
lives in a reference-counted structure, as per my usual practice in
similar cases elsewhere.
This is the main bulk of this boolification work, but although it's
making the largest actual change, it should also be the least
disruptive to anyone interacting with this code base downstream of me,
because it doesn't modify any interface between modules: all the
inter-module APIs were updated one by one in the previous commits.
This just cleans up the code within each individual source file to use
bool in place of int where I think that makes things clearer.
This commit removes the old #defines of TRUE and FALSE from puzzles.h,
and does a mechanical search-and-replace throughout the code to
replace them with the C99 standard lowercase spellings.
This shouldn't be a disruptive change at all: findloop_run and
findloop_is_loop_edge now return bool in place of int, but client code
should automatically adjust without needing any changes.
Now the flag passed to edsf_merge to say whether two items are the
same or opposite is a bool, and so is the flag returned via a pointer
argument from edsf_canonify.
The latter requires client code to be updated to match (otherwise
you'll get a pointer type error), so I've done that update in Loopy,
which is edsf's only current in-tree client.
Not many changes here: the 'dotted' flag passed to print_line_dotted
is bool, and so is the printing_in_colour flag passed to
print_get_colour. Also ps_init() takes a bool.
line_dotted is also a method in the drawing API structure, but it's
not actually filled in for any non-print-oriented implementation of
that API. So only front ends that do platform-specific _printing_
should need to make a corresponding change. In-tree, for example,
windows.c needed a fix because it prints via Windows GDI, but gtk.c
didn't have to do anything, because its CLI-based printing facility
just delegates to ps.c.
This changes parameters of midend_size and midend_print_puzzle, the
return types of midend_process_key, midend_wants_statusbar,
midend_can_format_as_text_now and midend_can_{undo,redo}, the 'bval'
field in struct config_item, and finally the return type of the
function pointer passed to midend_deserialise and identify_game.
The last of those changes requires a corresponding fix in clients of
midend_deserialise and identify_game, so in this commit I've also
updated all the in-tree front ends to match. I expect downstream front
ends will need to do the same when they merge this change.
encode_params, validate_params and new_desc now take a bool parameter;
fetch_preset, can_format_as_text_now and timing_state all return bool;
and the data fields is_timed, wants_statusbar and can_* are all bool.
All of those were previously typed as int, but semantically boolean.
This commit changes the API declarations in puzzles.h, updates all the
games to match (including the unfinisheds), and updates the developer
docs as well.
I noticed that state->common, which is shared between all the game
states in an undo chain, has a 'solved' flag in it. That's not right -
solvedness as a property of a particular state on the chain belongs in
the game_state itself, and having-at-one-point-been-solved-ness as a
persistent property of the whole chain belongs in the game_ui.
Fortunately, the game isn't actually doing it wrong:
state->common->solved is set once and then never read, so it must have
been left in from early abandoned code. Now removed.
latin_solver_diff_set takes a boolean input parameter to indicate
whether the 'Extreme'-level variant of set elimination is permitted.
But it's commented in the header file as having a boolean _output_
parameter which it sets if it _ended up_ using that variant. Probably
the latter was how it worked in an early draft, and I changed my mind
later without changing the comment.
In menu_save_event, we checked ctx.error to see if an errno value had
been left in it by the savefile_write callback, but if so, then we
were passing the _current_ value of errno to strerror() in place of
the saved value in ctx.error.
This may well have been benign, but I spotted it in an eyeball review
just now and thought I'd better fix it before it bit anyone.
To begin with, the toolchain no longer lets me build for x86-32 -
apparently MacOS is now 64-bit only.
Also, the linker now gives an error about a missing libgcc_s variant
for -mmacosx-version-min=10.4, and indeed 10.5. So I've bumped the
minimum supported OS version to 10.6.
That in turn required some changes in osx.m itself, because bumping
the min OS version caused some API deprecations to show up. Luckily I
turned out to have left myself a comment some time ago telling me what
I was going to need to do about one of them :-)
I've been playing this game a fair bit recently, and it's probably
time I jotted down some of the deductions I've been doing in my own
brain that the game doesn't know about. (Also I had an algorithmic
thought about the area-parity technique.)
For cube games, the minimum for any dimension should be 2, as there is
no net of the cube that is only one row/column. The previous logic
would permit a 1x7 game (for example) that could never be solved.
The read function used by midend_deserialise and friends is expected
never to perform a partial read (the main deserialisation code always
knows how many bytes it can expect to see), so it's specified to
return simply TRUE or FALSE for success/failure, rather than the
number of bytes read.
This probably wasn't breaking anything, since in the case of
deserialising from an internal memory buffer a short read could only
arise due to an outright bug constructing the buffer. But now I've
spotted it, I should fix it.
The JS code that retrieves the save-file data from emcc.c doesn't
receive a separate length value, but instead expects the data to be in
the form of a NUL-terminated string. But emcc.c wasn't NUL-terminating
it, so the save data could come out with random cruft on the end.
Instead of repeatedly reusing the file name 'PuzzleEngine.class' in
the main build directory, now each puzzle's NestedVM translation is
left in a separate subdirectory so that they don't collide with each
other. A bonus is that we don't have to rename the file back and forth
between the rule that builds it and the one that consumes it.
OS X is beginning to show a warning when a 32-bit application is
opened, so it's high time that this gets enabled. Fix a clang warning
exposed by this build.
This consists of setting a flag in the Info.plist. Everything in the
game is resolution-independent, of course, and has been thoroughly
tested on other platforms. The only issue I found is cosmetic: The
rounded window corners become more dramatic and don't look as good
against the square status bar.
Increasing the resolution also exposes two graphical quirks that I
don't think are new. Curved rails in Tracks seem to be made of short
segments that don't quite connect, but I don't see this on Android,
and on closer inspection this is already present on low resolution in
OS X. Lines in Untangle, and also Galaxies, that are at a multiple of
45 degrees seem thinner than other lines, but I also see this on
Android — I think it's just more obvious on high resolution, and could
be adjusted with antialiasing. Everything else looks as it should, for
example when moving a window between low and high dpi displays.
I've just upgraded my build machine to Ubuntu 18.04, which has come
with a version of javac that complains about both -source 1.3 and
-target 1.3. Both are surely pretty out of date anyway, so the path of
least resistance is to just increase them to the earliest version that
javac doesn't currently complain is deprecated.
If I want to rebuild just the Javascript puzzles (for example) in
circumstances where I don't expect to need a great many
edit-compile-link cycles, it's easier to get bob to do it for me than
to remember how to set up the development tools on my path. But it
takes ages to run the whole build script if I also have to wait for
the Windows, Mac and Java puzzles to be built, not to mention the
initial Unix build that runs for no purpose other than generating the
icon images.
So now I can run the build with various time-consuming parts
conditioned out, for development purposes. Of course, the default is
still to build absolutely everything.
Oops! This was left over from an early development version of commits
4408476b7 and 000ebc507, in which I initially arranged for each
adjacency list to be terminated with the sentinel value -1 instead of
separately storing an array of the lists' lengths.
I later changed the representation to make randomising the algorithm
easier (it's much easier to shuffle an array uniformly at random if
you _don't_ have to faff endlessly to work out its length). But this
write of a no-longer- needed sentinel value in the client code must
have survived the rewrite by mistake, and also somehow evaded all my
pre-commit testing with valgrind and asan.
A user reported that the Towers Javascript version was crashing on
startup, and I think this is the cause, because it seems to fix it for
me.
Checking with the standards, I think this is legal C99, but not legal
C89 - and we are compiling in C89 mode. Why _every_ version of gcc
didn't object, given all the warning and pedantry options, I'm not
sure, but one did, so I should fix it.
This function gives the front end a way to find out what keys the back
end requires; and as such it is mostly useful for ports without a
keyboard. It is based on changes originally found in Chris Boyle's
Android port, though some modifications were needed to make it more
flexible.
Its ability to solve general network flow problems was never actually
used in this code base; it was _always_ used for the restricted
problem of finding a matching in an unweighted bipartite graph. So now
I've switched all its clients over to the new matching.c, maxflow is
no longer needed.
Tents needs to construct maximal matchings in two different
situations. One is the completion check during play, in which the
existence of a perfect matching between tents and trees is part of the
win condition; the other is the initial grid generation, in which we
find a _maximal_ matching between the tents we've already placed and
all the possible neighbouring squares that are candidates for the tree
positions. Both of those are switched over.
The new client code is a lot smaller and nicer, because we can throw
away the col[] and num[] permutations entirely.
Of course, this also means that every puzzle that incorporated latin.c
now has to link against matching.c instead of maxflow.c - but since I
centralised that secondary dependency into Recipe a few commits ago,
it's trivial to switch them all over at once.