<feed xmlns='http://www.w3.org/2005/Atom'>
<title>puzzles/emcc.c, branch devel</title>
<subtitle>My sgt-puzzles tree</subtitle>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/'/>
<entry>
<title>Remove a comment suggesting use of localStorage for prefs</title>
<updated>2023-08-21T08:54:49+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-08-21T08:47:08+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=26a3b98f4f30de1f3faf0bb97eeeb8403864b5d3'/>
<id>26a3b98f4f30de1f3faf0bb97eeeb8403864b5d3</id>
<content type='text'>
Preferences in the JavaScript version _are_ stored in localStorage
now.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Preferences in the JavaScript version _are_ stored in localStorage
now.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: keep colour strings in JavaScript rather than in C</title>
<updated>2023-07-30T10:50:25+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-07-29T15:06:19+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=76da6ec140cbbdac6136469ce50aab40e218f398'/>
<id>76da6ec140cbbdac6136469ce50aab40e218f398</id>
<content type='text'>
The drawing routines in JavaScript used to take pointers to a C string
containing a CSS colour name.  That meant that JavaScript had to create
a new JavaScript string on ever call to a drawing function, which seemed
ugly.

So now we instead pass colour numbers all the way down into JavaScript
and keep an array of JavaScript strings there that can be re-used.  The
conversion from RGB triples to strings is still done in C, though.

This doesn't seem to have fixed either of the bugs I hoped it would, but
it does measurably improve drawing performance so I think it's worth
doing.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The drawing routines in JavaScript used to take pointers to a C string
containing a CSS colour name.  That meant that JavaScript had to create
a new JavaScript string on ever call to a drawing function, which seemed
ugly.

So now we instead pass colour numbers all the way down into JavaScript
and keep an array of JavaScript strings there that can be re-used.  The
conversion from RGB triples to strings is still done in C, though.

This doesn't seem to have fixed either of the bugs I hoped it would, but
it does measurably improve drawing performance so I think it's worth
doing.
</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>Expose the NO_EFFECT/UNUSED distinction through midend_process_key()</title>
<updated>2023-06-10T23:33:28+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-06-07T22:03:30+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=1547154efbfcf0bd8f6fc4f91fe99c26371fe0ee'/>
<id>1547154efbfcf0bd8f6fc4f91fe99c26371fe0ee</id>
<content type='text'>
This removed the "handled" pointer and instead extends the existing
boolean return value (quit or don't quit) into an enumeration.  One of
the values still quits the program, but now there are different values
for keys that had an effect, had no effect, and are not used by the
puzzle at all.  The mapping from interpret_move results to process_key
results is roughly:

move string    -&gt; PKR_SOME_EFFECT
MOVE_UI_UPDATE -&gt; PKR_SOME_EFFECT
MOVE_NO_EFFECT -&gt; PKR_NO_EFFECT
MOVE_UNUSED    -&gt; PKR_UNUSED

The mid-end can also generate results internally, and is the only place
that PKR_QUIT can arise.

For compatibility, PKR_QUIT is zero, so anything expecting a false
return value to mean quit will be unsurprised.  The other values are
ordered so that lower values indicate a greater amount of handling of
the key.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This removed the "handled" pointer and instead extends the existing
boolean return value (quit or don't quit) into an enumeration.  One of
the values still quits the program, but now there are different values
for keys that had an effect, had no effect, and are not used by the
puzzle at all.  The mapping from interpret_move results to process_key
results is roughly:

move string    -&gt; PKR_SOME_EFFECT
MOVE_UI_UPDATE -&gt; PKR_SOME_EFFECT
MOVE_NO_EFFECT -&gt; PKR_NO_EFFECT
MOVE_UNUSED    -&gt; PKR_UNUSED

The mid-end can also generate results internally, and is the only place
that PKR_QUIT can arise.

For compatibility, PKR_QUIT is zero, so anything expecting a false
return value to mean quit will be unsurprised.  The other values are
ordered so that lower values indicate a greater amount of handling of
the key.
</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>
<entry>
<title>emcc.c: remove savefile_read_ctx.</title>
<updated>2023-04-24T09:04:20+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-04-24T08:35:45+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=2b6d34adbd03a6110d4c2a0a0959eb6e30d3936d'/>
<id>2b6d34adbd03a6110d4c2a0a0959eb6e30d3936d</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
<entry>
<title>emcc.c: missing (void) in a function definition.</title>
<updated>2023-04-24T09:04:20+00:00</updated>
<author>
<name>Simon Tatham</name>
<email>anakin@pobox.com</email>
</author>
<published>2023-04-24T08:31:18+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=8c968483f8df7c30f78ff3998a397697a1699615'/>
<id>8c968483f8df7c30f78ff3998a397697a1699615</id>
<content type='text'>
This isn't C++, ahem.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This isn't C++, ahem.
</pre>
</div>
</content>
</entry>
<entry>
<title>js: Load save files into the C side incrementally</title>
<updated>2023-04-03T20:09:57+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-04-03T14:16:35+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=36c282aaa92bd42d570cdc76fe3b9e76d8da1ff1'/>
<id>36c282aaa92bd42d570cdc76fe3b9e76d8da1ff1</id>
<content type='text'>
Before this commit, JavaScript Puzzles loaded a save file by pushing the
entire file onto the Emscripten stack and then reading it from there.
This worked tolerably for typical save files, but Emscripten's stack
defaults to only having 64 kiB of space.  That meant that trying to load
something that wasn't a real save file tended to cause a stack overflow.
I expect that at least some real save files would suffer from the same
problem.

The stack overflow would generally cause a JavaScript exception and then
leave the stack pointer outside the stack, so that any future attempt to
call into C would fail as well.

To fix this, arrange that the C function for reading data from the save
file calls out to JavaScript.  The JavaScript can then copy just the
requested data into the caller's buffer.  We can't pass a JavaScript
function pointer to C, but since only one file can be loaded at a time,
we can just have a global variable that's the current loading callback.

There might still be a problem if you try to load a stupendously large
file, since I think FileReader.readAsArrayBuffer() reads the whole file
into the browser's RAM.  It works on my laptop with files up to a few
hundred megabytes, though.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Before this commit, JavaScript Puzzles loaded a save file by pushing the
entire file onto the Emscripten stack and then reading it from there.
This worked tolerably for typical save files, but Emscripten's stack
defaults to only having 64 kiB of space.  That meant that trying to load
something that wasn't a real save file tended to cause a stack overflow.
I expect that at least some real save files would suffer from the same
problem.

The stack overflow would generally cause a JavaScript exception and then
leave the stack pointer outside the stack, so that any future attempt to
call into C would fail as well.

To fix this, arrange that the C function for reading data from the save
file calls out to JavaScript.  The JavaScript can then copy just the
requested data into the caller's buffer.  We can't pass a JavaScript
function pointer to C, but since only one file can be loaded at a time,
we can just have a global variable that's the current loading callback.

There might still be a problem if you try to load a stupendously large
file, since I think FileReader.readAsArrayBuffer() reads the whole file
into the browser's RAM.  It works on my laptop with files up to a few
hundred megabytes, though.
</pre>
</div>
</content>
</entry>
<entry>
<title>New shared function, getenv_bool()</title>
<updated>2023-03-22T16:06:18+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-03-22T16:06:18+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=09c15f206edac18bd2158c189c821b9ba85d3939'/>
<id>09c15f206edac18bd2158c189c821b9ba85d3939</id>
<content type='text'>
This provides a standard way to get a boolean from an environment
variable.  It treats the variable as true iff its value begins with 'y'
or 'Y', like most of the current implementations.  The function takes a
default value which it returns if the environment variable is undefined.

This replaces the various ad-hoc tests of environment variable scattered
around and mostly doesn't change their behaviour.  The exceptions are
TOWERS_2D in Towers and DEBUG_PUZZLES in the Windows front end.  Both of
those were treated as true if they were defined at all, but now follow
the same rules as other boolean environment variables.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This provides a standard way to get a boolean from an environment
variable.  It treats the variable as true iff its value begins with 'y'
or 'Y', like most of the current implementations.  The function takes a
default value which it returns if the environment variable is undefined.

This replaces the various ad-hoc tests of environment variable scattered
around and mostly doesn't change their behaviour.  The exceptions are
TOWERS_2D in Towers and DEBUG_PUZZLES in the Windows front end.  Both of
those were treated as true if they were defined at all, but now follow
the same rules as other boolean environment variables.
</pre>
</div>
</content>
</entry>
<entry>
<title>More cleverness in midend_process_key()</title>
<updated>2023-02-23T23:16:18+00:00</updated>
<author>
<name>Ben Harris</name>
<email>bjh21@bjh21.me.uk</email>
</author>
<published>2023-02-23T22:32:53+00:00</published>
<link rel='alternate' type='text/html' href='https://www.franklinwei.com/cgit/puzzles/commit/?id=9dbcfa765ba59a8201425df18bec09c7bc334c5e'/>
<id>9dbcfa765ba59a8201425df18bec09c7bc334c5e</id>
<content type='text'>
It now strips off modifier flags from keys that shouldn't have them and
maps printable characters with MOD_CTRL to the corresponding control
characters.  It also catches Ctrl+Shift+Z because that obviously belongs
in the midend.

I've updated the JavaScript front-end to take advantage of these
changes.  Other front ends are unchanged and should work just as they
did before.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It now strips off modifier flags from keys that shouldn't have them and
maps printable characters with MOD_CTRL to the corresponding control
characters.  It also catches Ctrl+Shift+Z because that obviously belongs
in the midend.

I've updated the JavaScript front-end to take advantage of these
changes.  Other front ends are unchanged and should work just as they
did before.
</pre>
</div>
</content>
</entry>
</feed>
