Git log: commit a8b086239e4b35acb5b6f998654bdc01a9d4db7b
Author: Ben Hutchings <benh@debian.org>
Date: Thu Aug 28 02:32:20 2025 +0200
Regenerate PO-files
Gbp-Dch: ignore
commit 53a6d189c78ac0ee085c5b76368f1e95f8c46b93
Author: Ben Hutchings <benh@debian.org>
Date: Thu Aug 28 01:46:10 2025 +0200
slant: Do not shade filled squares with a faded slash
The new upstream version introduced a "Fade grounded components"
preference. When this is enabled, all slashes "grounded" (connected
to the border of the grid) are shown in a much lighter colour. This
interacts poorly with shading of filled squares, as the background is
then darker than the foreground slash.
Resolve this by reverting to the standard background colour in squares
that are filled with a faded slash.
commit 34d1631b6f880c9ea0d0519c16cc76625d1b2843
Author: Ben Hutchings <benh@debian.org>
Date: Wed Aug 27 02:24:56 2025 +0200
d/changelog: Bump version number, summarise upstream changes
Gbp-Dch: ignore
commit 97d802013fe912e05e24c0a284a593c431b271be
Author: Ben Hutchings <benh@debian.org>
Date: Wed Aug 27 01:56:04 2025 +0200
d/patches: Update for new upstream version
- Update "Apply version string substitutions from the tarball"
- Drop "Install both 48x48 and 96x96 icons", redundant with upstream
change to install all icon sizes
commit bc05b9e07e88a3b9d41b4489aed1743ed1e19c3b
Merge: b535191 a7c7826
Author: Ben Hutchings <benh@debian.org>
Date: Wed Aug 27 01:50:23 2025 +0200
Merge tag 'upstream/20250730.a7c7826' into debian/latest
Upstream version 20250730.a7c7826
commit a7c7826bce5cbb9b9c337c11b9b7f8b278e76fba
Author: Simon Tatham <anakin@pobox.com>
Date: Tue Jul 29 18:53:32 2025 +0100
Mines: fix a hang during grid generation.
The hang is reproducible, as of the code before this commit, by
running 'mines --generate 1 9x15n55X1Y1#2-94'.
What seems to happen is that the combination of [solver with
perturbations mixed in] gets stuck in a loop. At one end of the loop
there's a large square area cleared around the initial click, with
every square on the boundary being a mine. So the player can certainly
solve up to the boundary - but beyond the boundary they can't tell
what's a mine and what's not. So the perturber thinks about what to
do, and decides to fill _everything_ in the already-solved clear area
with mines from the unsolved area (leaving only a 3×3 region around
the initial click). That's no better, so the next run of the perturber
clears one extra row and column, and the next one does the same, and
so on, until we're back in the first situation. And since every time
we go round this loop we re-mark some squares as "not solved yet" and
then solve them, it looks as if progress is being made, and we don't
abandon the entire effort and restart from scratch, which is the usual
solution to any "stuck in a local optimum" problem.
This commit applies a simple and hopefully robust fix to get out of
the rut: we introduce a new notion of "progress" which doesn't count
re-solving a square that was solved before and then marked as undone
because of a perturbation. Now, after a couple of iterations around
that loop, the new nperturbs_since_last_new_open mechanism will notice
that no square has been opened _that was never opened before_ in too
long, and pull the plug.
I'm not at all happy with this fix. It should solve the immediate
hang, but I think probably what I _ought_ to do is rethink the entire
strategy of perturbation, in the large-scale case where we've run out
of perturbations we can make within a single 3×3 block and have to
fall back to either emptying or filling every single unknown square.
But fixing the immediate problem is a start!
commit 38b29910630048acecdbae08bd36f407135dc47c
Author: Simon Tatham <anakin@pobox.com>
Date: Tue Jul 29 18:52:21 2025 +0100
Mines: add extra diagnostics for grid perturbation.
A bug I was investigating was still confusing until I made the
perturber explain what it was doing in more detail.
commit e307c3426a92937724e7ccf97f7a1bf2b554f115
Author: Simon Tatham <anakin@pobox.com>
Date: Tue Jul 29 18:50:39 2025 +0100
Mines: fix a buffer overrun with -DSOLVER_DIAGNOSTICS.
We were printing a value from just outside the grid immediately
_before_ the bounds check that told us not to.
commit 7799786e640e1462583d82193547dae3152772ed
Author: Simon Tatham <anakin@pobox.com>
Date: Tue Jul 29 18:52:36 2025 +0100
Mines: allow params to control first-click location.
The string encoding of game_params can now include a location like
"X0Y5" at the end. This has no effect on interactive play (where the
game waits to see where the player first clicks), but in command-line
'mines --generate', it forces the pre-played first click to be at the
specified coordinates instead of randomised.
The idea is that this makes it easier to reproduce bugs that came up
in interactive play. For example, I ran across a bug this morning
which seems to come up more often when the first click is near a
corner.
commit dbe6378e23d573f89de1441ba62740ecb8c69c8b
Author: Alexander Tsoy <alexander@tsoy.me>
Date: Mon Jul 21 22:21:41 2025 +0300
Explicitly build core and common libraries as STATIC
Many Linux distributions build packages with BUILD_SHARED_LIBS option
enabled. As a result, add_library() defaults to SHARED instead of
STATIC, which causes the build to fail. Fix this by explicitly set type
to STATIC.
commit 880288cbbcb55b2f7b3520a45aefbfc2592dd362
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Jul 13 14:40:05 2025 +0100
X11: use the right timestamp for SetSelectionOwner.
When you set an X selection in response to an X event, you're supposed
to take the X server timestamp from the event and pass it back to the
SetSelectionOwner request, instead of just passing the cop-out value
CurrentTime.
I noticed the use of CurrentTime in a line modified by the previous
commit, and thought I'd see if it was easy to fix. It turns out it is:
GTK has a handy gtk_get_current_event_time() function, which will
return the event timestamp if you call it from within an event handler
responding to an X event, and default to CurrentTime if one isn't. So
it's very easy to tell GTK "please do the right thing if convenient".
(I presume that when GTK is using a backend other than X11, either all
of this is ignored anyway, or the same function call will find
something appropriate to do.)
commit 4c4d2624e4f9495a97c40be622b67f5cee5660c1
Author: Alexander Tsoy <alexander@tsoy.me>
Date: Sun Jul 13 15:58:35 2025 +0300
GTK: remove dependency on X11 headers
<X11/Xatom.h> header is not needed since 5062bee2ec70
Other headers doesn't seem to be needed as well.
commit 8314b038070839a2e5358cf10aa7da7f01616cf6
Author: Simon Tatham <anakin@pobox.com>
Date: Thu Jun 26 20:20:14 2025 +0100
Pearl: fix shortcut-loop detection on squares.
The final deduction technique in Tricky mode is to identify a
particular square and rule out one of the possible states it could be
in, by observing that that state would connect together two
already-connected things - hence forming a loop - but the loop would
be too small to include all the known non-blank squares, and therefore
couldn't be the true solution.
There were two bugs in this code. One would have made it rule out many
perfectly sensible square states and conclude that the puzzle had no
solution, if it hadn't been for the other bug, which prevented the
code from ever doing anything!
The 'never do anything' bug: in the small sub-loop that looked for the
common equivalence class of the two neighbouring squares we'd be
connecting, the output variable 'e' never had a valid value assigned
to it, because the assignment which should have done that was written
backwards, 'ee = e' instead of 'e = ee'.
With that fixed, the 'rule out perfectly sensible things' bug became
visible: if the square is already _known_ to connect a particular pair
of neighbours together, then it's not interesting that they're in the
same equivalence class, and doesn't mean we're about to form a loop at
all!
With both bugs fixed, a test run of 100 puzzle generations in Tricky
mode, 'pearl --generate 100 8x8dt#12345', generates 18 puzzles
differently after the change than before. All of those 18 puzzles
require this now-enabled deduction, and the old Pearl can't solve them
at all.
commit eff585c0da82598c68bcff21d78277b7417629b8
Author: Simon Tatham <anakin@pobox.com>
Date: Thu Jun 26 17:36:48 2025 +0100
Pearl: make a proper command-line solver.
The previous binary compiled as 'pearlsolver' was the combined
benchmark and soak test that CMakeLists.txt was _also_ building under
the name 'pearlbench'. There wasn't a solver program that you could
hand a game id to.
Now there is, and 'pearlsolver' is that. 'pearlbench' is unchanged.
commit fce4fcb062e2441855b5c22444298b8f6ab6f363
Author: Dan Sheppard <dan.sheppard.circle@gmail.com>
Date: Wed Jun 25 11:49:33 2025 +0100
dominosa: allow numeric keypad for number highlighting
dominosa: allow numeric keypad for number highlighting
Dan.
commit b589c5e296c13bc5b48c4016beeed9f1393d36cc
Author: Mike Edmunds <medmunds@gmail.com>
Date: Fri Jun 6 00:24:56 2025 -0700
grid.c: fix size miscalculation in Floret tiling.
Fixes swapped parameters that had been causing Loopy to draw Floret grids into
the right and bottom border areas.
commit 115bfb70d79ec3c3cdd61c29803453f401052009
Author: Mike Edmunds <medmunds@gmail.com>
Date: Fri Jun 6 00:18:12 2025 -0700
grid.c: generate full height Floret grid for width=1.
A Floret grid of height h alternates columns of h-1 and h hexagonal florets,
starting with h-1. With width 1, this resulted in a 1 x h-1 grid, rather than
the expected 1 x h.
commit 7deaf4d30531a555742b4528719e2a7d8f743d90
Author: Mike Edmunds <medmunds@gmail.com>
Date: Sun Jun 1 13:16:51 2025 -0700
Mosaic: use named fonttype.
commit b2f9946f64c1b2251e611d48bf13b18e46d5e4dd
Author: Mike Edmunds <medmunds@gmail.com>
Date: Thu Jun 12 09:32:26 2025 -0700
Palisade: Fix size miscalculation.
Palisade's size computation omitted the width of the rightmost and bottommost
grid edges, causing those lines to be drawn in the margin area.
commit 7615cdeebd9db1f05754f4c62c51da22b9f1fcc8
Author: Mike Edmunds <medmunds@gmail.com>
Date: Sun Jun 1 12:25:12 2025 -0700
Undead: use variable width font.
There doesn't seem to be any need for the fixed width font, and it looks
out of place compared to other puzzles.
commit 47bd72ce83ac17ad9b3643b0ad67feb57cafc46f
Author: Simon Tatham <anakin@pobox.com>
Date: Thu Jun 12 08:18:54 2025 +0100
Flood: stop using params->ncolours to set state->ncolours.
In Flood, the number of colours in the grid is a parameter only needed
at generation time: once you have a concrete grid description, the
number of colours can be inferred from that. The number of colours
isn't encoded in the short params string that goes with a descriptive
game id.
Therefore, it's a mistake to validate that game id against
params->colours, because it might be set wrong! A game id such as
3x3:123456789,10 will be rejected by validate_desc on the grounds that
it was given the default params->colours value of 6, and didn't like
the grid containing higher-numbered colours than that.
Worse, passing in a random-seed game id _with_ a number of colours has
a related bug. If you pass in a game id like "5x5c10#123" on the Flood
_command line_, or via a URL fragment id in the web version, then
new_game_desc is called with the correct value params->colours=10, but
the subsequent new_game is given the _persistent_ params structure
from the midend, in which the generation-time parameters haven't been
copied from the ones in the game id. So new_game gets a game
description string generated with 10 colours, but a game_params
claiming 6 colours, and sets state->colours to 6. This means new_game
is given a desc that validate_desc _would_ have rejected, but it
didn't get the chance to! This is bound to cause _some_ trouble. In
fact the specific trouble occurs when game_redraw uses the colour
value state->ncolours (i.e. supposedly just out of range) internally,
to calculate which squares to mark as the auto-solver's next move:
that "out of range" value is also used within the grid, so squares
unexpectedly get marked with the "next move" circle even if you're not
using the auto-solver, and then assertions fail when you try to do
anything.
The solution is simply to ignore params->ncolours for all purposes
_except_ new_game_desc. validate_desc now doesn't care what colour
values you pass in for grid squares except for ensuring they're within
the _global_ limit arising from how many RGB values we've defined. And
new_game sets state->colours by looking for the largest colour id
mentioned in the grid (although I could equally sensibly have just set
it to MAXCOLOURS unconditionally).
commit 7fa03051562ee81e2a5371f8b3a6d0bb6e646aa0
Author: Simon Tatham <anakin@pobox.com>
Date: Thu May 22 19:39:17 2025 +0100
Palisade: preference to clear complete regions.
Sometimes you complete a Palisade region by ruling out all its
internal edges one by one, clicking to change the initial "don't know"
line state into "definitely not a region border", and then you fill in
the edges. But sometimes a region is completed for another reason,
e.g. you completed all its surrounding regions before you'd thought
about this one particularly. Then it looks ugly to have the "don't
know" edges in a region that's finished already.
So here's a preference option to make completed regions look nicer. In
a complete region of exactly the right size, the internal edges are
shown as "definitely not" even if their logical state is "don't know".
It's very similar to Light Up's preference to stop showing the manual
"not a light" marks once a square is lit up: it means a fully solved
grid always looks nice, whether you bothered to clean it up by hand or
not.
This is a bit weird because it's a _display_-time change, so clicking
in the region won't change edge states back and forth - or rather, it
will, but you won't see the difference. Also it's slightly
patronising. So it's a user preference, and off by default.
commit 520b5871aed32c8b751183311b9131c046eab2c7
Author: Simon Tatham <anakin@pobox.com>
Date: Sun May 18 22:55:36 2025 +0100
Mines: put a warning on the web page about bug reports.
Mines is the puzzle that has attracted by far the largest number of
bug reports, including a great many claims that the "no guessing"
feature wasn't living up to its claims. But a bug has never actually
been found in the grid generation code. (The usual number of other
kinds of bug, just not _that_ bug.)
I've wondered for a while about putting some prominent text on the web
version of the puzzle stressing just how many of that kind of bug
report I've received and that all of them have been wrong, just to
encourage people to _try_ thinking again. So I went through my email
records and counted them. I make it 59 as of today, which is a slight
surprise, because it _felt_ more like 100-200 to me. Still, "over 50"
is a reasonable thing to write in the
It's an interesting question _why_ Mines gets all these false-positive
reports. One obvious possibility is simply that it's more popular than
the rest of the games in this collection. But a more interesting idea
is that perhaps players of ordinary Minesweeper, striving to get a
fast clearance time, are accustomed to not spending a lot of time
thinking about problems - instead, either open something quickly or
guess quickly, because if you guess you _might_ not get a good
time (kaboom!), but if you ponder for 30 seconds you _definitely_
won't get a good time.
commit 48a6f169c8fc48e11090a6e86e1f676fb455fd44
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Sun May 18 11:22:58 2025 +0100
GTK: add support for using a GdkFrameClock where available
GdkFrameClock was introduced in GDK 3.8. It should give us one callback
per video frame, which ought to give us precisely what we want for
animations. Testing shows that it does at does at least get us called
back at a suitable frequency, rather than dropping frames as the old
code does. I'm not sure it makes the animations visually any better,
though.
commit c747cbfbde9f4dd5eb21690aaddebde0c3ffffab
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Sat May 17 11:31:46 2025 +0100
GTK/Cairo: simplify do_blitter_load()
There's no need for a separate call to cairo_translate() when we can
apply an offset in cairo_set_source_surface() instead.
commit e374a5a8991c749dc0a4aa2e0b9947d109abb3fc
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Sat May 17 11:05:48 2025 +0100
GTK: correct offset when copying backing to window
When I removed the explicit code for handling non-unity scale factors
in favour of letting Cairo do the hard work, I accidentally simplified
draw_area() a little too much and removed the offsets that allow for
the fact that the puzzle surface doesn't necessarily fill the window,
meaning that the wrong parts of the surface tended to get painted into
the window. I've now corrected this.
commit c9070b4b40dcf1d1c5294bc827fe996a8925e7f5
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Fri May 16 20:12:50 2025 +0100
Remove BLITTER_FROMSAVED from drawing API
blitter_load had a feature whereby passing in BLITTER_FROMSAVED as both
x and y co-ordinates would cause them to be treated as whatever was last
passed to blitter_save() for the same blitter. But no back end has ever
used this feature, and the JavaScript front end has never implemented
it, so it's obviously not a very memorable feature. Moreover, it would
be quite reasonable to want to load from a blitter at (-1, -1), so
usurping those co-ordinates could cause surprising results.
I think if one did want this feature, it would be better implemented as
a separate function, but it doesn't seem like much trouble to let the
back end remember the co-ordinates.
I don't think this requires a change to the drawing API version number
because it will cause a compile failure in the (unlikely) event that
any third-party front end is actually using the feature.
commit 3b943d412f6acb7489fb9488c53113f63876f519
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Fri May 16 14:16:03 2025 +0100
Update reference Git commit in devel.but
I've read through the log and the only thing that was missing was
getenv_bool().
commit c610e24a56c3f54bbcf7f6ce56504d4feabc3454
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Fri May 16 14:01:27 2025 +0100
Document getenv_bool()
commit 6d09ad23b51ec5ce91ab135200315389c5548f8c
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Thu May 15 23:00:12 2025 +0100
GTK: avoid explicitly using Cairo image surfaces
Where we want to create a surface that's suitable for copying to and
from another surface, it's better to use cairo_surface_create_similar()
based on our window rather than explicitly creating an image surface.
This has two major advantages. First, it means that the surface is one
that can be copied easily to the target window (usually an Xlib surface
when running under X, for instance). Second, the new surface naturally
inherits the device scale from the original.
The first of these means that there's no longer any benefit in having a
separate pixmap when using Cairo, so USE_CAIRO_WITHOUT_PIXMAP becomes
equivalent to USE_CAIRO. The second means that a lot of code for
explicitly handling scale factors can be removed. Essentially the only
remaining reason for recording the scale factor is to detect when it
changes and re-create the backing surface.
There is one place where we still create an image surface, and that's
when running in headless mode to create icons.
commit 682119abebda4d0dbc233231a18b4735ffdfce10
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Wed May 14 20:52:58 2025 +0100
js: unwrap most drawing functions
After recent changes, most of the drawing functions in the JavaScript
front end were thin C wrappers around corresponding functions
implemented in JavaScript. Their only functionality was to discard
their first arguments, which is easily done in JavaScript instead.
So I've removed those wrapper functions and, in those cases, put
references to the JavaScript functions straight into the drawing_api
structure. This saves about 1 KB of wasm from each puzzle in my test
build.
commit 49aad96bb553fcc19f0535923b4ba0117f412902
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Tue May 13 22:52:49 2025 +0100
js: trust CanvasRenderingContext2D.drawImage() to DTRT
As far as I can tell, the specification for
CanvasRenderingContext2D.drawImage() requires it to sensibly handle
cases where the rectangle it's working on isn't entirely contained in
both the source and destination canvases. So there's not really any
reason for Puzzles to carefully trim the region being copied to their
intersection. This vastly simplifies a lot of the blitter-handling code
because it can just ask the user agent to copy the whole blitter back
and forth.
I've checked archived versions of the HTML spec back to 2014, and they
all say this should work. MDN doesn't suggest otherwise either. So I
think if this code was ever necessary, it's not any more.
commit b04e5b3531a8e08f2b884d42509e3bddb6f0291a
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Tue May 13 20:49:13 2025 +0100
js: index blitters Map by C address of blitter structure
C pointers appear as numbers in JavaScript and so they can be used to
index a Map. This removes the (admittedly rather theoretical) danger of
overflowing the blitter ID by repeatedly allocating and deallocating
blitters.
commit 86fc307f1956643dcb51965077f97b6548e6de6b
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Tue May 13 20:25:00 2025 +0100
js: replace blitters array with a Map
The array was growing by one element each time the puzzle was resized in
Guess, so is was a (minor) memory leak. The Map shouldn't have that
problem, though eventually the "id" counter will overflow.
commit 986ac69fb9ec5aaad04bc256c33d6ae4b3c0a13f
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Mon May 12 23:02:20 2025 +0100
js: handle most of the device pixel ratio in the front end
This makes the JavaScript front end work more like the GTK front end in
its handling of varying device pixel ratios, which GTK calls scale
factors. This is also an implementation of what I just described in
devel.but.
If the device pixel ratio is an integer, then the mid and back ends just
ge told about CSS logical pixels and the front end handles all the
necessary scaling itself, much like GTK. If the device pixel ratio
isn't an integer then this isn't possible. Instead we handle scaling by
the floor of the device pixel ratio in the front end, and pass the
remaining scaling factor to the mid end as the device pixel ratio. This
means that pressing Ctrl-+ in a browser still causes the canvas to grow
nicely, but on reaching a zoom of 200% the thin lines all get thicker.
I think this is a more or less ideal way to handle the device pixel
ratio, and in particular produces decent results without any effort in
back ends and without complicating the drawing API. It does need rather
a lot of front-end work, though.
commit 6a0d142f426e868bec99ea50c2d82d88ae7fdfac
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Sun May 11 11:56:02 2025 +0100
Describe front-end pixel scaling in devel.but
This adds two paragraphs. The first describes the model that the GTK
front-end uses, where a "pixel" in the drawing API can map to multiple
pixels in the pixmap used for drawing. To preserve pixel-accuracy,
this requires that there be an integer number of physical pixels to
each logical pixel, which happily is the case in GTK (at least up to
GTK 3).
The second paragraph attempts to explain how this relates to the
device_pixel_ratio provided to midend_size(). That's used by the
JavaScript front end and can cope with the arbitrary non-integer scale
factors thatr might be provided by Web browsers. However, it works by
just exposing physical pixels to the back end, which means that thin
lines tend to become hard to see as the physical pixels get small.
I think the best approach is actually a mixture of the two, where an
integer is factored out of the scale factor by the front end, and the
remaining factor (which should be < 2) is passed to midend_size(). I
haven't tried implementing this yet, though, so I might change my
mind.
commit 50985e9f2c54ad44e8c26491ddddd698bc02fd06
Author: Simon Tatham <anakin@pobox.com>
Date: Fri May 9 08:07:19 2025 +0100
Mosaic: make solver notice when it gets stuck.
The top-level solver loop had a boolean 'made_progress' among its loop
conditions, on the theory that if the solver got stuck then it would
fail to make progress and the loop would terminate after it had tried
everything it knew how to do. But made_progress started off as true,
and nothing ever set it to false, so this check never did anything!
Now we set made_progress to false at the start of each iteration of
the outermost while loop, and then if we scour the whole grid without
setting it to true, the while loop will stop and solve_game_actual()
will report failure.
commit 7da46412223273b3adf6d513466342b9d3a5c869
Author: Simon Tatham <anakin@pobox.com>
Date: Wed Feb 19 08:28:48 2025 +0000
Mosaic: fix one-byte-too-short buffer in solve_game().
Thanks to Jason Hood for the report. The crash is trivially reproduced
under Address Sanitizer if you set up the game id 15x15#12345 and then
use the Solve UI action.
commit b99f10727a17d84938ae75670945638ad67a8c95
Author: Hauke Rehr <hauke.rehr@uni-jena.de>
Date: Sun Feb 9 20:47:07 2025 +0100
slant: add preference: fading grounded components
Commit message added by SGT:
The general idea is that the puzzle constraint "you must not form a
loop" can also be phrased as "every grid vertex must have a path to
the boundary of the grid", on the basis that in a grid with every
square filled, any connected component of vertices _not_ joined to the
boundary by a path must instead be surrounded by a loop blocking every
way it could get there. So by changing the colour of each
"grounded" (connected to the boundary) grid edge, you draw the
player's attention to the components that don't yet have a path to the
edge, so they can consider the possible paths.
This is the kind of hint that users can very easily find to be
patronising and intrusive, not to mention a spoiler if they haven't
even made the leap from "no loops" to "everything must be grounded".
So it's a preference, and off by default.
This patch is somewhat rewritten from the submitted version, to
conform to local style and also compile in older C versions.
commit dc2407ed0ce90a15d8b494850964de74fe5ea7df
Author: Hauke Rehr <hauke.rehr@uni-jena.de>
Date: Tue Feb 11 07:36:33 2025 +0100
Use semantic enum entry names for pref indices
[Commit message added by SGT: this makes it easier to allocate indices
in the config_item array, and keep them in sync between get_prefs and
set_prefs for each game.]
commit 5edcabb967adb1b032bd46e4abb9c0015cd8a3c7
Author: Franklin Wei <franklin@rockbox.org>
Date: Fri Jan 3 21:58:31 2025 -0500
Group: implement game_get_cursor_location().
This should allow zoomed-in play on Rockbox.
commit 877133ae5d22f4bc99bfd43f6b1520a902755619
Author: Franklin Wei <franklin@rockbox.org>
Date: Fri Jan 3 00:37:21 2025 -0500
Group: implement game_request_keys().
This should allow keyboard-less play with Rockbox (and other front ends).
commit 1ece22b75827a9c310bc9311dc04ac006489ff54
Author: Franklin Wei <franklin@rockbox.org>
Date: Fri Jan 3 21:03:02 2025 -0500
Guess: make cursor visible at low resolution.
On many Rockbox devices, the cursor in Guess is invisible due to the low
screen resolution, which causes CGAP to round down to zero. This change
imposes a lower bound of 1 pixel.
Interestingly, this is less of an issue on front ends with antialiasing,
since the cursor peg's black border is overdrawn twice with, causing its
hazy antialiased boundary to get noticeably darker, even when CGAP is zero.
commit abe1eed3baa9617a7b52c861d159f832ffbba4c6
Author: Franklin Wei <franklin@rockbox.org>
Date: Wed Jan 1 18:49:13 2025 -0500
Untangle: fix redraws when dragging with cursor keys.
The recent addition of graph editor functionality to Untangle in
2ac951e broke redraws while dragging a point using the cursor keys. In
particular, the new ui->dragtype field was not being set by the cursor
dragging code path, causing redraws to erroneously exit early.
Generally, there is quite a bit of code duplication between the cursor
and mouse dragging code paths in interpret_move(). Some refactoring
could perhaps reduce the chances of this happening again.
commit 28e519b08fde9fe0f0b3c4d5d8a84e17a8337231
Author: Franklin Wei <franklin@rockbox.org>
Date: Fri Jan 3 00:43:22 2025 -0500
Clarify documentation of request_keys() and button2label().
I'm starting to question why the "label" field of the key_label struct
is dynamically allocated in the first place. Only Undead sets it to
anything other than NULL, and I see no reason that wouldn't work with
statically allocated string constants.
(Doing some archaeology shows that the dynamically allocated "label"
field was introduced by... me! I can only wonder what I was thinking 7
years ago when I first wrote that code. But that's a problem for
another time...)
commit 79be403101d055d2fde3611a5f133135d4094ee9
Author: James Sutton <james.mark.sutton@gmail.com>
Date: Sun Dec 29 18:22:40 2024 +1300
GTK 3: account for window scale in blitter.
Commit 97a0dc0 adjusted the backing surface size based on the GTK
window scale, and used cairo_scale so that drawing code is oblivious
to this. The blitter operates on the underlying pixels and so should
account for the scaling, but no code was added for this.
Now we multiply the blitter dimensions by the window scale, scale the
pixel coordinates to save from, and set the scaling factor to 1:1 when
loading. This fixes rendering artefacts with "GDK_SCALE=2", or when
using display scaling with Wayland.
Also adjust the backing surface position in draw_area so that it is
centered properly.
commit 5eea14c6c3814484d7c74c885e88f48095e93d53
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Dec 22 20:08:14 2024 +0000
groupsolver: fix assertion failure.
Reproduced via 'groupsolver -v 5i:p1g4' (thanks to Arun Giridhar for
the report).
The Group-specific solver_hard() function ruled out a bunch of
possibilities by deducing various things that couldn't be the group
identity, but forgot to set done_something = true, so that it return 0
claiming it hadn't done anything.
So latin_solver_top progressed to the next difficulty level and tried
recursion. And latin_solver_recurse failed an assertion because it was
surprised to find a cell with only one possibility - it expected that
the _simple_ deductions would have ruled out any of those, which they
would have if solver_hard() had returned >0, because the loop would
have reset to the top and tried the easy deductions again after
solver_hard() had given them something to work with.
commit 59954d67f56b353ee560fa261071bf23141fb940
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Dec 22 11:55:50 2024 +0000
groupsolver: fix segfault accessing solver->names.
Reproduced via 'groupsolver -v 5i:l5_2b5h' (thanks to Arun Giridhar
for the report).
We had filled in subsolver.names, but then called
latin_solver_alloc(&subsolver), which nulled out that pointer again.
Solution: do those two things in the opposite order.
commit 5099e4c6d466b0d47069bfbdf1ac94727e669381
Author: Bo Lindbergh <blgl@stacken.kth.se>
Date: Fri Dec 20 18:00:53 2024 +0100
Cosmetic fix for mouse-to-tile coordinate transformation.
Clicking just outside the left or top edges of the grid in Pattern
has the same effect as clicking just inside the same edge.
This happens because the FROMCOORD macro uses integer division,
which rounds towards zero rather than towards negative infinity.
One way to fix this is to add TILE_SIZE before the division
and subtract 1 afterwards.
commit 5e7400403c2f711352255f373b50850d4b2f4e63
Author: Kyle Swarner <kyds@parkourpizza.com>
Date: Thu Nov 21 11:55:38 2024 -0500
Untangle: allow frontends to alter some dimensions.
This change to Untangle allows for custom frontends to optionally
define their own CIRCLE_RADIUS and DRAG_THRESHOLD parameters.
Rationale: The hardcoded values provided here (specifically a 6px
circle radius) is far too small for many modern pixel-dense devices,
requiring frontends to duplicate files locally to fix. Adding #ifndef
conditionals around these two values allow them to be configured by
the frontend without the need to fork the files.
The changes here are what I made to support my custom iOS
frontend (Puzzles Reloaded) and work well.
commit 8e83f39eb989d36f10fcf4be7c4dd5eaa0e69f02
Author: Evgeny Kapun <abacabadabacaba@gmail.com>
Date: Mon Nov 4 14:00:29 2024 +0000
Signpost: fix an out-of-bounds read.
Occurs when dragging with RMB outside the grid to unlink a path segment.
This bug was discovered using ASan.
commit ebb50f0af28591bb1bf28368d62c066333aeb12f
Author: Evgeny Kapun <abacabadabacaba@gmail.com>
Date: Mon Nov 4 13:59:43 2024 +0000
Bridges: fix an out-of-bounds read.
Occurs when dragging from an island next to an edge in the direction
of that edge.
This bug was discovered using ASan.
commit 05f4f6349fd9e65cccb96e7b46cf65d0802ed52d
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Oct 20 19:08:11 2024 +0100
Pattern: fix crash when printing.
The mostly-unpopulated game_drawstate created in game_print for the
sake of the TILE_SIZE macro was being passed to a subroutine which
expected another field of it to be filled in.
Rather than continue filling in one field at a time, let's just make a
complete one.
commit 182b3d9e27981c03df07cc86d8f794ad218dc350
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Sep 27 22:28:57 2024 +0100
Pattern: fix three bugs in game_text_format.
A user reported that, on the default square board size, the clues were
printed in the right places, but the grid contents were accidentally
transposed by swapping the x and y coordinates. Oops!
Trying to reproduce this, my dev build was running under ASan, which
pointed out two further buffer handling bugs. The initial sprintf put
the terminating NUL one char too early in the buffer, so that it was
overwritten by the bottom right corner of the grid and no NUL ended up
in the buffer at all; also, the separate buffer for formatting numeric
clues in the left margin was sized one char too short, because the NUL
at the end of it hadn't been counted. Apparently in a non-ASan
environment both of those could work anyway by chance.
commit a9601a678a0613b388a1bcbd5141759acf6a577f
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Sep 27 12:51:34 2024 +0100
Untangle: fix a memory leak.
Spotted by Leak Sanitiser while re-testing after the previous commits:
the separately allocated 'crosses' array in game_state was never freed.
commit b535191a3d158af1aeb58ac85500074449ab4642
Author: Ben Hutchings <benh@debian.org>
Date: Sun Jun 4 03:03:17 2023 +0200
d/changelog: Open new upstream entry, summarise upstream changes
Gbp-Dch: ignore
commit 432f103678401c606770a9852597e67f7ed36988
Author: Ben Hutchings <benh@debian.org>
Date: Sun Jun 4 00:12:04 2023 +0200
d/patches: Update PO files
commit cc14d68902d4782d28bfcb1482862c712e169778
Author: Ben Hutchings <benh@debian.org>
Date: Sun Jun 4 00:09:15 2023 +0200
d/patches: Update for new upstream
- Update "Apply version string substitutions from the tarball"
- Refresh "Add HTML-based online help"
commit 8aa8cf3ff8edd0b11317852be5d2854d456fd9c6
Merge: e9c2065 b6c842a
Author: Ben Hutchings <benh@debian.org>
Date: Sun Jun 4 00:06:50 2023 +0200
Merge tag 'upstream/20230527.b6c842a'
Upstream version 20230527.b6c842a
commit b6c842a28cf6597df063fcff35079c3e3982381e
Author: Simon Tatham <anakin@pobox.com>
Date: Fri May 26 21:29:29 2023 +0100
Emscripten: fix edge case of js_canvas_find_font_midpoint.
If the puzzle canvas is at a ludicrously small size, so that you
attempt to use a zero-height font, then obviously nothing sensible
will appear in the way of text, but you'd at least like to avoid a
crash. But currently, js_canvas_find_font_midpoint will make a canvas,
print some height-0 text into it, and try to retrieve the image pixels
to see what the actual font height was - and this will involve asking
getImageData for a zero-sized rectangle of pixels, which is an error.
Of course, there's only one possible return value from this function
if the font height is 0, so we can just return it without going via
getImageData at all.
(This crash can be provoked by trying to resize the puzzle canvas to
Far Too Small, or by interleaving canvas resizes with browser-tab
zooming. I've had one report that it also occurs in less silly
situations, which I haven't been able to reproduce. However, this
seems like a general improvement anyway.)
commit 8237b02be4e6f92a9e1aebbed23d7b5de0e3543c
Author: Simon Tatham <anakin@pobox.com>
Date: Sun May 7 21:41:50 2023 +0100
Loopy: fix redraw issue due to enlarged dots.
dot_bbox() wasn't taking into account the new size of the dots, so
sometimes a rectangle of the grid would be redrawn without a partial
dot it should have contained, because nothing had noticed that that
dot overlapped that rectangle.
Actually I'm not sure why this bug wasn't happening _before_ I
enlarged the dots, because the previous code seemed to think dots had
a fixed size in pixels regardless of tile size, which wasn't even
true _before_ my recent commit 4de9836bc8c36cd. Perhaps it did occur,
just never while I was watching.
commit d0f97926e80482d9cbb3679165a09ca6e695f83f
Author: Simon Tatham <anakin@pobox.com>
Date: Fri May 5 12:51:25 2023 +0100
Isolate icons build from the running user's preferences.
Preferences that adjust the display, such as Pearl graphics style or
Light Up lit-blobs toggling, shouldn't affect the official icons, even
if a ~/.config/sgt-puzzles exists in the account that builds the
puzzles.
commit 63346a8ceac9ac1061e59af2a99ab1a44c851392
Author: Simon Tatham <anakin@pobox.com>
Date: Wed May 3 12:57:27 2023 +0100
Windows: reorganise menu ids.
A user pointed out today that IDM_PREFS overlaps the second preset,
because I forgot that IDM_PRESETS was not a single id but the base for
an open-ended series.
Looking more closely, there are several other problems with the IDM_*
constants. IDM_GAMES (used in COMBINED mode) shouldn't be at an
arbitrary distance _above_ IDM_PRESETS, because that risks a
collision; instead, the games' and presets' ids should interleave.
Also, the ids above IDM_GAMES were going up in steps of 1, which
should have been 0x10, for the usual reason that the bottom four bits
of the id aren't guaranteed. And IDM_KEYEMUL was completely unused (I
suspect it was part of the discarded WinCE support).
Now the #defines that are the bases of series are labelled as
IDM_FOO_BASE; they interleave as they should; and there's a clear
comment.
commit 89e9026ee49fd5469ad989e629effd2e4f6ade2a
Author: Simon Tatham <anakin@pobox.com>
Date: Tue May 2 19:51:29 2023 +0100
midend_apply_prefs: apply prefs to the right ui.
The function takes a game_ui pointer as an argument, and then ignores
it and unconditionally applies the midend's saved preferences to me->ui.
commit e0bb6d3b8546ea67e79cb190a96c26961ddacdf6
Author: Simon Tatham <anakin@pobox.com>
Date: Mon May 1 14:24:56 2023 +0100
Untangle: add a 'snap to grid' user preference.
Requested by a user who otherwise found themself spending too much
time struggling to get lines nicely horizontal or vertical.
The implementation is easy, but the question is what size of grid is
appropriate. Untangle's own generated games are constructed by making
a planar graph drawn on an extremely coarse grid - but snapping to
_that_ grid would give away information about the puzzle solution, and
also, Untangle wouldn't know any similar information about graphs
generated by any other method.
So a better approach is to choose a size of grid that guarantees that
_any_ graph with n vertices can be drawn on it with nonintersecting
straight edges. That sounds like a tricky maths problem - but happily,
the solution is given in a book I already had a copy of. References in
a comment (plus a proof of a pedantic followup detail about multiple
planar embeddings).
commit 628cc6785b2cfa3d4ee6101667e4bb9e11095eec
Author: Simon Tatham <anakin@pobox.com>
Date: Mon May 1 13:49:54 2023 +0100
Untangle: replace manual int64 bodging with int64_t.
Where possible, that is. If our compilation environment has provided
int64_t, we can just make our int64 type be that, and not have to mess
around with multi-word arithmetic at all.
commit c48a9f44ffdd2bd2055a5296c84874716dd303b9
Author: Simon Tatham <anakin@pobox.com>
Date: Mon May 1 13:42:43 2023 +0100
Replace check of __STDC_VERSION__ with HAVE_STDINT_H.
Just spotted this in puzzles.h. We don't need to guess any more from
the C standards version whether stdint.h is available: we've actually
checked _precisely that_ in cmake, so it's better to use the answer.
commit 4de9836bc8c36cddead5e9efc6beff0692118b1e
Author: Simon Tatham <anakin@pobox.com>
Date: Sat Apr 29 14:10:40 2023 +0100
Loopy: slightly increase the size of dots.
In the Hats tiling, each tile has two consecutive edges collinear.
When both edges are turned on, i.e. drawn in black just like the dot,
it becomes _just slightly_ tricky to spot the dot in the middle of
that straight line, which is important if you're counting edges around
the face to check a clue.
Increasing the radius from 2/32 to 3/32 of tile size is far too big.
2.5/32 seems reasonable, though.
commit b293605ce34bd28dea013c25ed801e123b47e98c
Author: Simon Tatham <anakin@pobox.com>
Date: Sat Apr 29 13:40:51 2023 +0100
hat-test: fix memory leaks.
I ran this again today with Leak Sanitiser on, which complained.
commit bbbbc8b22bae0aa15b48273f763b0e215df0c7af
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Mon Apr 24 22:25:12 2023 +0100
Pattern: Reduce row clue spacing if there are lots of them
Normally, we put two spaces between row clues, but if there are a lot
then even with a smaller font size they might overflow the left edge
of the window. To compensate, go down to one space between clues
instead of two if there are a lot of them. On my laptop the GTK build
demonstrates overflow with "13x1:1//1//1//1//1//1//1/1.1.1.1.1.1.1".
commit fcf1d274c3f512e6f70cba71832e0ecc97b656d3
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Mon Apr 24 22:12:30 2023 +0100
Pattern: switch to small font when there are many row clues
If you have a particularly large number of clues in a row, they can
end up falling off the left edge of the window. This used not to be a
problem because the rendering code would squash them closer together
if necessary. But then I switched to drawing them all as a single
string (so that two-digit row clues would get enough space with a
large font) and that broke the old mechanism.
Now we detect if there are enough clues that our conservative guess at
the string length looks like overflowing in the big font, and switch
to the small one if necessary. If we had a drawing call to measure a
string then we could be cleverer about this, but we don't.
This problem can be demonstrated with "7x1:1//1//1//1/1.1.1.1" in the
GTK port with the fonts my laptop has.
I think overflow can still occur even with a small font, so once I've
demonstrated that I'll try to fix it.
commit 42cc7f6cb0bfb99255e94c86e3c155bc1c9fd0e1
Author: Ben Harris <bjh21@bjh21.me.uk>
Date: Mon Apr 24 21:45:02 2023 +0100
Correct a comment in Pattern's clue-drawing code
commit 20d424bf1bef4c1ed249ec3c72a859deb926e207
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 14:24:19 2023 +0100
Emscripten: change the localStorage key used for preferences.
I picked pathname + "#preferences" because Ben suggested either that
or pathname + "/preferences", and I thought the former sounded neater.
But Ben now suggests that it might be better to avoid using # in the
key, just in case anyone should later want to use the whole URL
_including_ the fragment ID as the key for some other localStorage
usage - for example, autosaved progress per puzzle _instance_, keying
off the puzzle URL with a fragment ID in the game description.
So, per Ben's replacement suggestion, change the "#" to a space.
commit 43db4aa38e83595dc6df245cb952795f9f306ed0
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 10:17:33 2023 +0100
Support user preferences in the Emscripten frontend.
Here, user preferences are stored in localStorage, so that they can
persist when you come back to the same puzzle page later.
localStorage is global across a whole web server, which means we need
to take care to put our uses of it in a namespace reasonably unlikely
to collide with unrelated web pages on the same server. Ben suggested
that a good way to do this would be to store things in localStorage
under keys derived from location.pathname. In this case I've appended
a fragment id "#preferences" to that, so that space alongside it
remains for storing other things we might want in future (such as
serialised saved-game files used as quick-save slots).
When loading preferences, I've chosen to pass the whole serialised
preferences buffer from Javascript to C as a single C string argument
to a callback, rather than reusing the existing system for C to read
the save file a chunk at a time. Partly that's because preferences
data is bounded in size whereas saved games can keep growing; also
it's because the way I'm storing preferences data means it will be a
UTF-8 string, and I didn't fancy trying to figure out byte offsets in
the data on the JS side.
I think at this point I should stop keeping a list in the docs of
which frontends support preferences. Most of the in-tree ones do now,
and that means the remaining interesting frontends are ones I don't
have a full list of. At this moment I guess no out-of-tree frontends
support preferences (unless someone is _very_ quick off the mark), but
as and when that changes, I won't necessarily know, and don't want to
have to keep updating the docs when I find out.
commit 2b6d34adbd03a6110d4c2a0a0959eb6e30d3936d
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 09:35:45 2023 +0100
emcc.c: remove savefile_read_ctx.
It wasn't ever used! Looks as if I pasted it in here from one of the
other implementations, before realising that wasn't how I was going to
read save files at all.
commit 8c968483f8df7c30f78ff3998a397697a1699615
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 09:31:18 2023 +0100
emcc.c: missing (void) in a function definition.
This isn't C++, ahem.
commit 12b2608b241743314f177e73d8d73b72580d2948
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 09:56:35 2023 +0100
Fix bounds check in buffer_append.
We're about to append one character to the buffer _and_ put a \0 after
it, so we need the buffer to be at least _two_ characters longer than
where the current position is.
I think this bug would have had a hard time showing up in normal use,
but I managed to trigger it by completely messing up a prototype
Emscripten preferences implementation, and a good thing too.
commit bf453043db68342de85028c7a44cb75262e02ad9
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 08:44:40 2023 +0100
Support user preferences in the Mac frontend.
The low-level load and save routines are basically copy-pasted from
gtk.c, with only minor changes to deal with the different locally
appropriate config file location and the lack of savefile_write_ctx.
commit 81680583fd5af8a1fd9b1ee30d5fa3dfc073832a
Author: Simon Tatham <anakin@pobox.com>
Date: Mon Apr 24 08:35:42 2023 +0100
GTK save_prefs: fix a wrongly sourced error report.
After a failed rename(), we should find out what went wrong by looking
in errno itself, not in wctx->error which reported a problem in the
previous step.
commit e080e0e3253a079ac755bb6d21ff08a6ccd96815
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 22:34:40 2023 +0100
Slant: actually check ui->swap_buttons.
Apparently I wrote the new-look code that sets up the prefs field in
the UI, but didn't remember to rewrite the code in interpret_move that
ought to read it.
commit f01b1674bd862e1792b5216bd5d832cd52a170ae
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 14:58:31 2023 +0100
GTK: stop referring to &thegame in prefs I/O functions.
I had to do this in the Windows front end to cope with compiling in
both COMBINED and one-puzzle mode: you can't refer to &thegame because
it might not exist in this build, so instead, if you want to load/save
preferences for a given midend, you ask that midend for _its_ game
structure, and use that to make the necessary file names.
On Unix, we don't have COMBINED mode. But now I've thought of it, this
seems like a good idiom anyway, for the sake of futureproofing against
the day someone decides to implement combined mode on Unix.
delete_prefs() doesn't get passed a frontend _or_ a midend, so that
just has to take a bare 'const game *' parameter, and in main() we
pass &thegame to it. So that will still need changing in a combined
mode, if one is ever added.
commit 1fa28340e8e8d8459456469c72f7156ccf1493f1
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 14:54:29 2023 +0100
Support user preferences on Windows.
This is done using basically the same methods as on Unix, and just
translating the system calls in save_prefs to a different API.
commit 35cd44c563ec58e00a89109ef1f5450b08a3faa6
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 14:53:11 2023 +0100
make_prefs_path(): tolerate NULL inputs.
Just noticed that if prefs_dir() returns NULL, we'll already have
passed it to this function before the calling functions get round to
checking. I think it's less wordy all round to make this helper
function propagate NULL than to mess about with lots of extra if
statements in between all the calls.
commit 5c0def1850b2c09af300f09cd48f714f2505d217
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 14:16:17 2023 +0100
Document the new Net preference.
Naturally, I only remembered to do this after 'git push'.
commit 2d91261eb3a37b919f48450888f8f5bfd226c053
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 14:02:39 2023 +0100
Net: preference for how loop highlighting interacts with locking.
Net's loop highlighting detects any loop in the current state of the
grid. I've occasionally found that to be a bit of a spoiler, since
sometimes it can point out a deduction I should make before I've
figured it out for myself - e.g. when I've just locked all but two of
the squares involved in the loop, and the last two _just happen_ to be
oriented so as to complete the loop. In that situation I'd prefer if
the loop _didn't_ immediately light up and point out to me that I need
to arrange that those squares aren't connected to each other.
The simple answer is to only count edges connecting two _locked_
squares, for the purposes of loop detection. But this is obviously
unacceptable to some players - in particular, those who play without
the locking feature at all. So it should be a user preference.
commit c0bd524848f98e5c4a495c4bc31dd55087a28aaa
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 14:00:40 2023 +0100
Fix failure to update me->ui when changing preferences.
This must have been introduced during a last-minute rebase, or similar
- I'm sure it worked a couple of days ago! Because midend_set_config
passed a NULL game_ui to midend_set_prefs, the latter would make up a
temporary UI and apply the changes to that. As a result, the midend's
main UI would keep the original backend preferences, and those would
also be the ones saved to the config file.
commit e2add4185cf1e3639b7a320384098d63dc2f3d67
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 11:00:58 2023 +0100
GTK: add a command-line --delete-prefs option.
If you want to remove your saved preferences for a puzzle for any
reason (perhaps because of one of those unsympathetic managers, or
perhaps because it's become corrupted in some way), you can of course
manually go and find the config file and delete it. But if you're not
sure where it is, it's helpful to have a method of telling the puzzle
itself to delete the config file.
Perhaps it would be useful to expose this in the GUI as well, though
I'm not quite sure where is the best place to put it.
(_Perhaps_ it would also be useful to have a more thorough option that
deleted _all_ puzzles' configurations - although that would involve
telling every separate puzzle binary in this collection what all the
other ones' names are, which would be an entirely new build headache.)
commit 6c66e2b2de63b6a8159835516ee229bda3253bc2
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 10:58:53 2023 +0100
Support preferences in the GTK frontend.
Finally, some user-visible behaviour changes as a payoff for all that
preparation work! In this commit, the GTK puzzles get a 'Preferences'
option in the menu, which presents a dialog box to configure the
preference settings.
On closing that dialog box, the puzzle preferences are enacted
immediately, and also saved to a configuration file where the next run
of the same puzzle will reload them.
The default file location is ~/.config/sgt-puzzles/<puzzlename>.conf,
although you can override the .config dir via $XDG_CONFIG_HOME or
override the Puzzles-specific subdir with $SGT_PUZZLES_DIR.
This is the first commit that actually exposes all the new preferences
work to the user, and therefore, I've also added documentation of all
the current preference options.
commit 4752c7a2d9bd83d41d418b31b931a9bb9af219fa
Author: Simon Tatham <anakin@pobox.com>
Date: Sun Apr 23 10:09:27 2023 +0100
Universal preference option for one-key shortcuts.
With this option turned off (it's on by default), the single-letter
keyboard shortcuts like 'q' for quit and 'n' for new game don't
function any more. You can still access the same functions via more
complicated shortcuts like Ctrl-Q or Ctrl-N, and front ends can
provide any other UI they like for the same operations, but this way,
people aren't at risk of blowing away half an hour of puzzling with
one misaimed key.
This is a thing people have occasionally asked for, and I've generally
resisted on the grounds that I have sympathy for people playing
puzzles at work who need to be able to close the game quickly when an
unsympathetic boss wanders by. But now we have a preferences system,
we can cater to those people _and_ the ones who don't mind.
More immediately useful: adding _at least one_ universal preference in
the initial version of this system means that there will be no games
with no preference options at all, and therefore, no need to put
conditionals all through the participating frontends to deal with
whether the Preferences menu option should even be provided. That
would have been a waste of time because all those conditionals would
just have to be removed again as soon as the first universal
preference came along - so adding an easy one _now_ means we can save
the effort of putting in the temporary conditionals in the first
place.
commit bb1ab36108942ed9b0c84bf68e22869994467a2a
Author: Simon Tatham <anakin@pobox.com>
Date: Sat Apr 22 12:54:11 2023 +0100
Keep a set of preferences in the midend.
This commit introduces a serialisation format for the user preferences
stored in game_ui, using the keyword identifiers that get_prefs is
required to write into its list of config_item. As a result, the
serialisation format looks enough like an ordinary config file that a
user could write one by hand.
The preferences for the game backend are kept in serialised form in
me->be_prefs. The typical use of this is to apply it to a just-created
game_ui by calling midend_apply_prefs(), which deserialises the prefs
buffer into a list of config_item and passes it to the backend's
set_prefs function, overwriting the preference fields (but no others)
of the game_ui.
This is duly done when creating a new game, when loading a game from a
save file, and also when printing a puzzle. To make the latter work,
document_add_puzzle now takes a game_ui (and keeps ownership of it
afterwards), and passes that to the backend's compute_size and print
functions.
The backend's own get_prefs and set_prefs functions are wrapped by
midend_get_prefs and midend_set_prefs. This is partly as a convenience
(it deals with optionally constructing a game_ui specially to call the
backend with), but mostly so that there will be a convenient place in
the midend to add standard preferences applying across all puzzles.
No cross-puzzle preferences are provided yet.
There are two external interfaces to all this, and in this commit,
neither one is yet called by any frontend:
A new pair of midend functions is exposed to the front end, called
midend_load_prefs and midend_save_prefs. These have a similar API to
midend_serialise and midend_deserialise, taking a read/write function
pointer and a context. So front ends that can already load/save a game
to a file on disk should find it easy to add a similar set of
functions loading/saving user preferences.
Secondly, a new value CFG_PREFS is added to the enumeration of
configuration dialog types, alongside the ones for the Custom game
type, entering a game description and entering a random seed. This
should make it easy for frontends to offer a Preferences dialog,
because it will operate almost exactly like three dialogs they already
handle.
commit ea6be8f0af766ed15b19260ae17fa793d3d6d4d8
Author: Simon Tatham <anakin@pobox.com>
Date: Sat Apr 22 10:51:37 2023 +0100
Require games to accept new_ui(NULL) if they have preferences.
This will be necessary in the next commit, so that the midend can make
a game_ui out of nothing in order to store preferences in it.
The only game actually affected by this requirement is Pearl, which
has a preference (GUI style) and also allocates space based on the
game_state's grid size to store the coordinates of a path being
dragged, so if there is no game_state, it can't do the latter - which
is OK, because it also won't be expected to.
commit d13ece698f02288c56cf46f3a20ecc1aaf8004f5
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Apr 21 16:19:49 2023 +0100
Generalise the midend serialisation callbacks.
These are currently only used for internal serialisation of midend
state in order to undo/redo across New Game, and are named
accordingly. But I'm about to reuse them for another set of
serialisation functions, so they'll want more general names, and also
need to be moved higher up in the source file so as to have been
defined where I'll want to use them.
commit 0058331aeb027f7441a04d99cc7c1e445bd896d9
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Apr 21 15:50:05 2023 +0100
New backend functions: get_prefs and set_prefs.
These are similar to the existing pair configure() and custom_params()
in that get_prefs() returns an array of config_item describing a set
of dialog-box controls to present to the user, and set_prefs()
receives the same array with answers filled in and implements the
answers. But where configure() and custom_params() operate on a
game_params structure, the new pair operate on a game_ui, and are
intended to permit GUI configuration of all the settings I just moved
into that structure.
However, nothing actually _calls_ these routines yet. All I've done in
this commit is to add them to 'struct game' and implement them for the
functions that need them.
Also, config_item has new fields, permitting each config option to
define a machine-readable identifying keyword as well as the
user-facing description. For options of type C_CHOICES, each choice
also has a keyword. These keyword fields are only defined at all by
the new get_prefs() function - they're left uninitialised in existing
uses of the dialog system. The idea is to use them when writing out
the user's preferences into a configuration file on disk, although I
haven't actually done any of that work in this commit.
commit 0d1a1f08bac25a4641c38a8e42dfa6e2bb9981d7
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Apr 21 15:41:18 2023 +0100
Move per-puzzle ad-hoc getenv preferences into game_ui.
Environment variables that set specific settings of particular
puzzles, such as SLANT_SWAP_BUTTONS, LIGHTUP_LIT_BLOBS and
LOOPY_AUTOFOLLOW, now all affect the game behaviour via fields in
game_ui instead of being looked up by getenv in the individual
functions that need to know them.
The purpose of this refactoring is to put those config fields in a
place where other more user-friendly configuration systems will also
be able to access them, once I introduce one. However, for the moment,
there's no functional change: I haven't _yet_ changed how the user
sets those options. They're still set by environment variables alone.
All I'm changing here is where the settings are stored inside the
code, and exactly when they're read out of the environment to put into
the game_ui.
Specifically, the getenvs now happen during new_ui(). Or rather, in
all the puzzles I've changed here, they happen in a subroutine
legacy_prefs_override() called from within new_ui(), after it's set up
the default values for the settings, and then gives the environment a
chance to override them. Or rather, legacy_prefs_override() only
actually calls getenv the first time, and after that, it's cached the
answers it got.
In order to make the override functions less wordy, I've altered the
prototype of getenv_bool so that it returns an int rather than a bool,
and takes its default return value in the same form. That way you can
set the default to something other than 0 or 1, and find out whether a
value was present at all.
This commit only touches environment configuration specific to an
individual puzzle. The midend also has some standard environment-based
config options that apply to all puzzles, such as colour scheme and
default presets and preset-menu extension. I haven't handled those
yet.
commit a4fca3286f3aa630a3641e50a8e1f44ab1504a29
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Apr 21 15:30:41 2023 +0100
Pass a game_ui to compute_size, print_size and print.
I'm about to move some of the bodgy getenv-based options so that they
become fields in game_ui. So these functions, which could previously
access those options directly via getenv, will now need to be given a
game_ui where they can look them up.
commit ec2e2f37703e1da4bb097c27ae5e7f1fa368624b
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Apr 21 16:12:43 2023 +0100
Missing const in configure() documentation.
Commit de67801b0fd3dfa changed the 'name' field from char * to const
char *, but didn't update the docs to match. Better late than never.
commit 20606f0fea14fecae55efa7fef4314a2f999ddc3
Author: Simon Tatham <anakin@pobox.com>
Date: Fri Apr 21 09:26:14 2023 +0100
Filling: switch to using dsf_minimal in minimize_clue_set.
Turns out that was another case where we were assuming the canonical
dsf element was also the minimal one, because we process the clues in
order and expect to start a linked list at the canonical element of
each region and then add the rest of the cells to the existing one.
Easily fixed by using the minimal element again.
commit ce203c12efe0e10445a3be56c4308db42d9086c8
Author: Simon Tatham <anakin@pobox.com>
Date: Thu Apr 20 19:41:46 2023 +0100
Loopy: draw even faint lines using draw_thick_line.
When playing on a high-DPI screen and running Loopy at a large tile
size to compensate, the faint lines along grid edges in LINE_NO state
are exceptionally hard to see, because they're still only one pixel
wide even when everything else has been expanded.
This has been true for ages, but it's more significant now, because
the new Hats tiling mode needs a lot of counting of edges in all
states (since the hats have 14 edges in total!), and it's awkward not
to be able to see exactly where the LINE_NO edges are, or where an
edge between two other tiles meets this hat's outline.
commit 777dbffd4219be87190803be876ec3924aa92aee
Author: Simon Tatham <anakin@pobox.com>
Date: Thu Apr 20 19:38:09 2023 +0100
Turn off Leak Sanitiser in the icons build.
If you configure a Linux build of Puzzles with -fsanitize=address, it
will fail during the icons build, because the icon-maker programs leak
memory when they're run, and by default, this causes ASan to report
all the memory leaks at the end of the program *and then exit 1*.
I don't think 'just fix the memory leaks' is a viable answer. _Some_
of the leaks come from the Puzzles code, and could be fixed by being
more punctilious about freeing everything before exiting (although
that is not necessary for any actually sensible purpose and would
_only_ serve to stop Leak Sanitiser complaining). But some are outside
the Puzzles code completely, apparently from fontconfig. So even if we
fixed all the leaks we could find, we wouldn't prevent the failure
status.
When I want to build with ASan, I've been working around this by
setting ASAN_OPTIONS=detect_leaks=0 in the environment before running
the build command. Easier all round if we just do that _inside_ the
cmake setup.
commit 9f08986cf1b5dd58fc618e54ba45b85e7ba10cc9
Author: Simon Tatham <anakin@pobox.com>
Date: Thu Apr 20 15:13:06 2023 +0100
Update the documentation for the dsf functions.
Easier to do this all in one go after I've finished messing about.