<feed xmlns='http://www.w3.org/2005/Atom'>
<title>puzzles/cmake, 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>Add a 'core' library alongside 'common'.</title>
<updated>2023-06-16T17:32:55+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-06-15T06:40:14+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=de13ca2874e673b426efcf04f734ae6625635396'/>
<id>de13ca2874e673b426efcf04f734ae6625635396</id>
<content type='text'>
The 'core' library contains almost all the same objects as 'common',
but leaves out hat.c. And the auxiliary program 'hatgen' now links
against that slightly reduced core library instead of 'common'.

This avoids a dependency loop: one of hatgen's jobs is to generate
hat-tables.h, but hat-tables.h is a dependency of it.

Of course, the generated hat-tables.h is already committed, so this
doesn't present a bootstrapping problem in a normal build. But if
someone modifies hatgen.c in order to regenerate hat-tables.h, and
does so in a way that makes it uncompilable, they can't rebuild hatgen
and try again! Of course you can always revert changes with git, but
it's annoying to have to. Better to keep the dependencies non-cyclic
in the first place.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The 'core' library contains almost all the same objects as 'common',
but leaves out hat.c. And the auxiliary program 'hatgen' now links
against that slightly reduced core library instead of 'common'.

This avoids a dependency loop: one of hatgen's jobs is to generate
hat-tables.h, but hat-tables.h is a dependency of it.

Of course, the generated hat-tables.h is already committed, so this
doesn't present a bootstrapping problem in a normal build. But if
someone modifies hatgen.c in order to regenerate hat-tables.h, and
does so in a way that makes it uncompilable, they can't rebuild hatgen
and try again! Of course you can always revert changes with git, but
it's annoying to have to. Better to keep the dependencies non-cyclic
in the first place.
</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>
</feed>
