<feed xmlns='http://www.w3.org/2005/Atom'>
<title>puzzles/cmake/platforms, branch master</title>
<subtitle>My sgt-puzzles tree</subtitle>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/'/>
<entry>
<title>Reset non-WASM Firefox version back to 48.</title>
<updated>2024-03-01T12:42:15+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2024-03-01T12:42:15+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=db804ea5a1d2de8d9d7d6e8fe569f5f8ec231832'/>
<id>db804ea5a1d2de8d9d7d6e8fe569f5f8ec231832</id>
<content type='text'>
That's what the comment said I'd left it at, but in some kind of
editing goof, I failed to actually do so.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
That's what the comment said I'd left it at, but in some kind of
editing goof, I failed to actually do so.
</pre>
</div>
</content>
</entry>
<entry>
<title>Emergency fix to Puzzles WASM builds.</title>
<updated>2024-03-01T12:31:33+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2024-03-01T12:24:05+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=cc91f8b9deafbf284609e3511ff900104499da9c'/>
<id>cc91f8b9deafbf284609e3511ff900104499da9c</id>
<content type='text'>
I updated Emscripten recently, to version 3.1.54. The result was that
none of the WASM puzzles run any more, because they produce a stack
trace at startup with the error message "to do setValue(i64) use
WASM_BIGINT".

I don't fully understand this. The stack trace comes via a JS wrapper
around a WASM-compiled function called __main_argc_argv, which sounds
like something in the Emscripten library startup. Somewhere in there
it goes via _js_get_date_64(), which tries to write an i64 into the
WASM memory array, which hits this abort in setValue().

Web searching for the error message turned up
https://github.com/godotengine/godot/pull/88594 which gave me the clue
that '-s WASM_BIGINT' is a command-line setting for the Emscripten
linker. And indeed, setting that makes the startup-time error go away
and the puzzles run again. But it also causes older versions of all
browsers to be unsupported, presumably on the grounds that they don't
have whatever WASM bigint feature this flag causes the code to use.

I don't really understand what's going on here. I assume
_js_get_date_64 is being called to handle a 64-bit time_t. But the
Puzzles code doesn't work with time_t at all, so this is entirely in
the Emscripten standard library. And if the pre-main() startup code
needs a 64-bit integer write, which won't work without this flag, then
surely _nothing_ would work without this flag, and surely someone
would have noticed that, and made that flag the default? This all
seems confusing and I wonder if I've misunderstood something.

However, if I don't fix it in _some_ way, the web puzzles will stay
out of action for days and I'll get lots of email complaints. So
here's something that makes them basically work again, and maybe we
can figure out the rest of the story later.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
I updated Emscripten recently, to version 3.1.54. The result was that
none of the WASM puzzles run any more, because they produce a stack
trace at startup with the error message "to do setValue(i64) use
WASM_BIGINT".

I don't fully understand this. The stack trace comes via a JS wrapper
around a WASM-compiled function called __main_argc_argv, which sounds
like something in the Emscripten library startup. Somewhere in there
it goes via _js_get_date_64(), which tries to write an i64 into the
WASM memory array, which hits this abort in setValue().

Web searching for the error message turned up
https://github.com/godotengine/godot/pull/88594 which gave me the clue
that '-s WASM_BIGINT' is a command-line setting for the Emscripten
linker. And indeed, setting that makes the startup-time error go away
and the puzzles run again. But it also causes older versions of all
browsers to be unsupported, presumably on the grounds that they don't
have whatever WASM bigint feature this flag causes the code to use.

I don't really understand what's going on here. I assume
_js_get_date_64 is being called to handle a 64-bit time_t. But the
Puzzles code doesn't work with time_t at all, so this is entirely in
the Emscripten standard library. And if the pre-main() startup code
needs a 64-bit integer write, which won't work without this flag, then
surely _nothing_ would work without this flag, and surely someone
would have noticed that, and made that flag the default? This all
seems confusing and I wonder if I've misunderstood something.

However, if I don't fix it in _some_ way, the web puzzles will stay
out of action for days and I'll get lots of email complaints. So
here's something that makes them basically work again, and maybe we
can figure out the rest of the story later.
</pre>
</div>
</content>
</entry>
<entry>
<title>Emscripten build: stop setting MIN_EDGE_VERSION.</title>
<updated>2024-02-29T07:55:38+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2024-02-29T07:54:24+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=e20644a3baa70dfd5baf790047ce821b396df312'/>
<id>e20644a3baa70dfd5baf790047ce821b396df312</id>
<content type='text'>
Emscripten 3.1.51 withdrew support for legacy (pre-Chrome) Edge
completely, and this command-line option now provokes an error from
the compiler.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Emscripten 3.1.51 withdrew support for legacy (pre-Chrome) Edge
completely, and this command-line option now provokes an error from
the compiler.
</pre>
</div>
</content>
</entry>
<entry>
<title>Windows: add a VERSIONINFO resource to the puzzle binaries.</title>
<updated>2023-11-19T15:12:47+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-11-19T11:54:48+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=08365fb260ae6e32442dd9f196e65d13facb4b33'/>
<id>08365fb260ae6e32442dd9f196e65d13facb4b33</id>
<content type='text'>
This includes the textual version number in its existing
form (yyyymmdd followed by an abbreviated git hash). The four-part
binary version is set to 1 followed by year, month and day; if I ever
want to change that, I can increment the initial 1.

FileDescription is taken from the existing DESCRIPTION string provided
to each puzzle() statement in CMakeLists.txt.

This means that puzzles.rc now always defines at least one resource,
so we can remove the workaround for MinGW's windres not being able to
cope with an empty .rc file, which added a dummy resource in the
absence of an icon.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This includes the textual version number in its existing
form (yyyymmdd followed by an abbreviated git hash). The four-part
binary version is set to 1 followed by year, month and day; if I ever
want to change that, I can increment the initial 1.

FileDescription is taken from the existing DESCRIPTION string provided
to each puzzle() statement in CMakeLists.txt.

This means that puzzles.rc now always defines at least one resource,
so we can remove the workaround for MinGW's windres not being able to
cope with an empty .rc file, which added a dummy resource in the
absence of an icon.
</pre>
</div>
</content>
</entry>
<entry>
<title>Windows: leave puzzles.rc out of auxiliary GUI tools.</title>
<updated>2023-11-19T15:04:50+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-11-19T15:03:40+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=595338fa43d40f356f04b8704f72f060651669e8'/>
<id>595338fa43d40f356f04b8704f72f060651669e8</id>
<content type='text'>
There's no reason to put the .rc file into developer tools like
galaxieseditor at all. Its current job is to add an icon, and those
tools don't have any. I'm about to add version information, and they
won't have that either (in particular, no description string like the
games do).

The CLI developer tools already don't include puzzles.rc, and GUI dev
tools are more like those than they are like puzzles.

puzzles.rc was being added to an aux GUI tool's source file list by
get_platform_puzzle_extra_source_files(), which is called for aux GUI
tools as well as for puzzles proper. However, it's not as simple as
just eliminating that call, because on Unix, we _do_ need to add the
same extra source files to GUI dev tools that we do for puzzles,
because gtk.c contains external references to either an array of the
puzzle's icons or an empty array indicating that there aren't any, so
_something_ has to provide that.

So instead, get_platform_puzzle_extra_source_files now takes an extra
argument saying whether the program is a real puzzle or an aux tool;
windows.cmake leaves out puzzles.rc in the latter case, but unix.cmake
puts the icon array in unconditionally.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
There's no reason to put the .rc file into developer tools like
galaxieseditor at all. Its current job is to add an icon, and those
tools don't have any. I'm about to add version information, and they
won't have that either (in particular, no description string like the
games do).

The CLI developer tools already don't include puzzles.rc, and GUI dev
tools are more like those than they are like puzzles.

puzzles.rc was being added to an aux GUI tool's source file list by
get_platform_puzzle_extra_source_files(), which is called for aux GUI
tools as well as for puzzles proper. However, it's not as simple as
just eliminating that call, because on Unix, we _do_ need to add the
same extra source files to GUI dev tools that we do for puzzles,
because gtk.c contains external references to either an array of the
puzzle's icons or an empty array indicating that there aren't any, so
_something_ has to provide that.

So instead, get_platform_puzzle_extra_source_files now takes an extra
argument saying whether the program is a real puzzle or an aux tool;
windows.cmake leaves out puzzles.rc in the latter case, but unix.cmake
puts the icon array in unconditionally.
</pre>
</div>
</content>
</entry>
<entry>
<title>Refactor the new icon installation code.</title>
<updated>2023-07-14T07:40:06+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-07-14T07:40:06+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=6de17a7511bf67e999c450851d5bc9e4892367bb'/>
<id>6de17a7511bf67e999c450851d5bc9e4892367bb</id>
<content type='text'>
It's horribly repetitive, and we had a list of all the icons' pixel
sizes anyway!
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It's horribly repetitive, and we had a list of all the icons' pixel
sizes anyway!
</pre>
</div>
</content>
</entry>
<entry>
<title>Install the icons to the right location on Linux</title>
<updated>2023-07-14T07:31:44+00:00</updated>
<author>
<name>Emmanuel Gil Peyrot</name>
<email>linkmauve@linkmauve.fr</email>
</author>
<published>2023-07-13T17:30:05+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=c99fbed8c9d957de5b2094b54c7ec7e38979d770'/>
<id>c99fbed8c9d957de5b2094b54c7ec7e38979d770</id>
<content type='text'>
That way, any application displaying the .desktop with its icon will
pick the icon size it deems the best one for the current rendering.

See the Icon Theme Specification:
https://specifications.freedesktop.org/icon-theme-spec/latest/ar01s07.html

Signed-off-by: Emmanuel Gil Peyrot &lt;linkmauve@linkmauve.fr&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
That way, any application displaying the .desktop with its icon will
pick the icon size it deems the best one for the current rendering.

See the Icon Theme Specification:
https://specifications.freedesktop.org/icon-theme-spec/latest/ar01s07.html

Signed-off-by: Emmanuel Gil Peyrot &lt;linkmauve@linkmauve.fr&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>js: Copy-to-clipboard support</title>
<updated>2023-07-05T18:39:57+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-07-05T18:39:57+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=ad7042db989eb525defea9298b2b14d564498473'/>
<id>ad7042db989eb525defea9298b2b14d564498473</id>
<content type='text'>
Now using the browser's "copy" operation while the focus is in the
puzzle will copy the puzzle state to the clipboard.  Browsers seem to
have odd ideas about whate element to target with the "copy" event:
Firefox targets the parent of the &lt;canvas&gt; while Chromium targets the
&lt;body&gt;.  To cope with these and possible future weirdness I attach the
event handler to the document and then look to see if it's plausibly
related to the canvas.

Arguably we might want to handle a wider range of "copy" events, maybe
any where the selection isn't empty.  I'm not sure, though, so we'll
start with the minimal change.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Now using the browser's "copy" operation while the focus is in the
puzzle will copy the puzzle state to the clipboard.  Browsers seem to
have odd ideas about whate element to target with the "copy" event:
Firefox targets the parent of the &lt;canvas&gt; while Chromium targets the
&lt;body&gt;.  To cope with these and possible future weirdness I attach the
event handler to the document and then look to see if it's plausibly
related to the canvas.

Arguably we might want to handle a wider range of "copy" events, maybe
any where the selection isn't empty.  I'm not sure, though, so we'll
start with the minimal change.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: pass preferences file from JS to C on the heap, not the stack</title>
<updated>2023-05-30T15:00:31+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-05-30T14:55:22+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=5acce15ed907d29a5575668a09e7d94cf7a36b3f'/>
<id>5acce15ed907d29a5575668a09e7d94cf7a36b3f</id>
<content type='text'>
The C stack used by Emscripten is quite small, so passing more than a
few klilobytes of data on it tends to cause an overflow.  Current
versions of puzzles will only generate tiny preferences files, but this
might change in future and in any case Puzzles shouldn't crash just
because the preferences in local storage have got corrupted.

To fix this, we now have JavaScript allocate a suitable amount of C heap
memory using malloc() and stick the preferences file in there.

This could plausibly fail if the preferences file were really big, but
that's unlikely since browsers generally limit an origin to about 5 MB
of local storage.  In any case, if malloc() does fail, we'll just ignore
the preferences file, which is probably the right thing to do.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The C stack used by Emscripten is quite small, so passing more than a
few klilobytes of data on it tends to cause an overflow.  Current
versions of puzzles will only generate tiny preferences files, but this
might change in future and in any case Puzzles shouldn't crash just
because the preferences in local storage have got corrupted.

To fix this, we now have JavaScript allocate a suitable amount of C heap
memory using malloc() and stick the preferences file in there.

This could plausibly fail if the preferences file were really big, but
that's unlikely since browsers generally limit an origin to about 5 MB
of local storage.  In any case, if malloc() does fail, we'll just ignore
the preferences file, which is probably the right thing to do.
</pre>
</div>
</content>
</entry>
<entry>
<title>Support user preferences in the Emscripten frontend.</title>
<updated>2023-04-24T09:17:33+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-04-24T09:17:33+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=43db4aa38e83595dc6df245cb952795f9f306ed0'/>
<id>43db4aa38e83595dc6df245cb952795f9f306ed0</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
</feed>
