Debian Package Tracker
Register | Log in
Subscribe

sgt-puzzles

Simon Tatham's Portable Puzzle Collection - 1-player puzzle games

Choose email to subscribe with

general
  • source: sgt-puzzles (main)
  • version: 20230410.71cf891-2
  • maintainer: Ben Hutchings (DMD)
  • arch: any
  • std-ver: 4.5.0
  • VCS: Git (Browse, QA)
versions [more versions can be listed by madison] [old versions available from snapshot.debian.org]
[pool directory]
  • o-o-stable: 20191231.79a5378-3+deb11u1
  • oldstable: 20230122.806ae71-2
  • stable: 20230410.71cf891-2
  • testing: 20230410.71cf891-2
  • unstable: 20230410.71cf891-2
versioned links
  • 20191231.79a5378-3+deb11u1: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
  • 20230122.806ae71-2: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
  • 20230410.71cf891-2: [.dsc, use dget on this link to retrieve source package] [changelog] [copyright] [rules] [control]
binaries
  • sgt-puzzles (12 bugs: 0, 2, 10, 0)
action needed
2 bugs tagged patch in the BTS normal
The BTS contains patches fixing 2 bugs, consider including or untagging them.
Created: 2025-01-06 Last update: 2025-09-19 01:01
version in VCS is newer than in repository, is it time to upload? normal
vcswatch reports that this package seems to have a new changelog entry (version 20250730.a7c7826-1, distribution UNRELEASED) and new commits in its VCS. You should consider whether it's time to make an upload.

Here are the relevant commit messages:
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.
Created: 2025-08-25 Last update: 2025-09-17 21:03
AppStream hints: 40 warnings normal
AppStream found metadata issues for packages:
  • sgt-puzzles: 40 warnings
You should get rid of them to provide more metadata about this software.
Created: 2020-03-23 Last update: 2023-01-24 22:01
debian/patches: 8 patches to forward upstream low

Among the 8 debian patches available in version 20230410.71cf891-2 of the package, we noticed the following issues:

  • 8 patches where the metadata indicates that the patch has not yet been forwarded upstream. You should either forward the patch upstream or update the metadata to document its real status.
Created: 2023-02-26 Last update: 2023-06-04 06:43
Standards version of the package is outdated. wishlist
The package should be updated to follow the last version of Debian Policy (Standards-Version 4.7.2 instead of 4.5.0).
Created: 2020-11-17 Last update: 2025-02-27 13:24
news
[rss feed]
  • [2023-06-13] sgt-puzzles 20230410.71cf891-2 MIGRATED to testing (Debian testing watch)
  • [2023-06-03] Accepted sgt-puzzles 20230410.71cf891-2 (source) into unstable (Ben Hutchings)
  • [2023-05-15] Accepted sgt-puzzles 20191231.79a5378-3+deb11u1 (source) into proposed-updates (Debian FTP Masters) (signed by: Ben Hutchings)
  • [2023-04-22] sgt-puzzles 20230122.806ae71-2 MIGRATED to testing (Debian testing watch)
  • [2023-04-17] Accepted sgt-puzzles 20230122.806ae71-2 (source) into unstable (Ben Hutchings)
  • [2023-04-16] Accepted sgt-puzzles 20230410.71cf891-1 (source) into experimental (Ben Hutchings)
  • [2023-01-29] sgt-puzzles 20230122.806ae71-1 MIGRATED to testing (Debian testing watch)
  • [2023-01-24] Accepted sgt-puzzles 20230122.806ae71-1 (source) into unstable (Ben Hutchings)
  • [2022-08-07] sgt-puzzles 20220801.89391ba-1 MIGRATED to testing (Debian testing watch)
  • [2022-08-01] Accepted sgt-puzzles 20220801.89391ba-1 (source) into unstable (Ben Hutchings)
  • [2022-07-31] Accepted sgt-puzzles 20220613.387d323-1 (source) into unstable (Ben Hutchings)
  • [2022-02-21] sgt-puzzles 20191231.79a5378-6 MIGRATED to testing (Debian testing watch)
  • [2022-02-16] Accepted sgt-puzzles 20191231.79a5378-6 (source) into unstable (Ben Hutchings)
  • [2022-02-14] Accepted sgt-puzzles 20191231.79a5378-5 (source) into unstable (Ben Hutchings)
  • [2022-02-14] Accepted sgt-puzzles 20191231.79a5378-4 (amd64 source) into unstable (Ben Hutchings)
  • [2020-02-08] sgt-puzzles 20191231.79a5378-3 MIGRATED to testing (Debian testing watch)
  • [2020-02-02] Accepted sgt-puzzles 20191231.79a5378-3 (source) into unstable (Ben Hutchings)
  • [2020-01-31] Accepted sgt-puzzles 20191231.79a5378-2 (source) into unstable (Ben Hutchings)
  • [2020-01-31] Accepted sgt-puzzles 20191231.79a5378-1 (source) into unstable (Ben Hutchings)
  • [2020-01-26] sgt-puzzles REMOVED from testing (Debian testing watch)
  • [2019-12-10] sgt-puzzles 20170606.272beef-1 MIGRATED to testing (Debian testing watch)
  • [2019-09-01] sgt-puzzles REMOVED from testing (Debian testing watch)
  • [2017-08-22] sgt-puzzles 20170606.272beef-1 MIGRATED to testing (Debian testing watch)
  • [2017-08-17] Accepted sgt-puzzles 20170606.272beef-1 (source) into unstable (Ben Hutchings)
  • [2017-01-28] sgt-puzzles 20161228.7cae89f-1 MIGRATED to testing (Debian testing watch)
  • [2017-01-18] Accepted sgt-puzzles 20161228.7cae89f-1 (source) into unstable (Ben Hutchings)
  • [2016-07-25] sgt-puzzles 20160429.b31155b-1 MIGRATED to testing (Debian testing watch)
  • [2016-07-20] Accepted sgt-puzzles 20160429.b31155b-1 (source) into unstable (Ben Hutchings)
  • [2016-07-16] sgt-puzzles REMOVED from testing (Debian testing watch)
  • [2014-10-07] sgt-puzzles 20140928.r10274-1 MIGRATED to testing (Britney)
  • 1
  • 2
bugs [bug history graph]
  • all: 12
  • RC: 0
  • I&N: 2
  • M&W: 10
  • F&P: 0
  • patch: 2
links
  • homepage
  • buildd: logs, reproducibility, cross
  • popcon
  • browse source code
  • edit tags
  • other distros
  • security tracker
  • screenshots
  • l10n (-, 100)
  • debian patches
ubuntu Ubuntu logo [Information about Ubuntu for Debian Developers]
  • version: 20230410.71cf891-2build2
  • 3 bugs

Debian Package Tracker — Copyright 2013-2025 The Distro Tracker Developers
Report problems to the tracker.debian.org pseudo-package in the Debian BTS.
Documentation — Bugs — Git Repository — Contributing