1679 Commits

Author SHA1 Message Date
ebb079eca0 Loopy: make line thicknesses scale with the canvas.
This is now important due to Ben's changes in the web frontend. On
high-DPI displays, the canvas is the same overall size as before, but
it's scaled up by increasing the game's tilesize rather than the
browser scaling the image after the game redraws.

Loopy ought to have been scaling its line thicknesses all along, but
forgot. Easily fixed.
2022-10-28 21:32:14 +01:00
1e8169ea94 js: Take device pixel ratio into account when setting default size
This is a bit of a hack.  When setting the puzzle to its default size,
either at startup or from a right-click on the resize handle, we now
scale the default size from midend_size() by the device pixel ratio,
and then pass that back to midend_size().  This does more or less the
right thing, in that the puzzle now starts up at a size that scales
with the font size.

There are still some slight inconsistencies, where sequences of DPR
changes and puzzle parameter changes can have order-dependent effects
on the size of the puzzle.  Happily these effects are small and fairly
hard to observe.
2022-10-27 22:51:54 +01:00
fa58dd85b7 js: Distinguish manual resizes from device pixel ratio changes
This adds a new callback, rescale_puzzle(), that's called when the
device pixel ratio changes.  This means that resize_puzzle() can safely
set the nominal canvas size, which means that manual resizing of the
puzzle now sticks.

Still missing: paying attention to the device pixel ratio when choosing
the initial (or reset) size.
2022-10-27 22:51:54 +01:00
9783bbfbc0 js: Split setting nominal and actual canvas size
Now zooming in and out repeatedly doesn't cause the canvas to wither
away, but user resizes don't stick any more.  Still more to do.
2022-10-27 22:51:54 +01:00
532d662722 js: Very bad attempt at making puzzles change size when zooming
This has the entertaining consequence that repeatedly zooming in and out
causes puzzles to gradually shrink, thus demonstrating that recording
the nominal size correctly will be necessary.
2022-10-27 22:51:48 +01:00
5af0cd4ac1 js: Add a CMake variable to control whether Emscripten emits WASM
I've finally got bored of keeping (and occasionally losing) a patch
that turns it off unconditionally.
2022-10-27 09:59:04 +01:00
6f5debe417 js: Make update_pixel_ratio more backward-compatible
Despite my stylistic downgrades, it still used two features not present
in Firefox 48, and hence KaiOS 2.5: passing options to addEventListener,
and calling addEventListener on a MediaQueryList at all.  Now it uses
the older addListener method and explicitly removes each listener as
soon as it's called.
2022-10-26 21:57:53 +01:00
7354790ca4 js: Use String.replace() in place of .replaceAll()
The latter turns out to be a little too new for KaiOS 2.5, but
.replace() will do global replacements if fed a RegExp.
2022-10-26 21:23:54 +01:00
5fae5ca0db js: Be more subtle about cancelling keydown events
Now we only cancel a keydown event if the C keyboard handler recognises
the key and passes it on to the midend.  This doesn't necessarily mean
that the midend has actually done anything with it, of course.  Still,
this is enough to allow F12 to open the developer tools even when the
input focus is on the puzzle.  It also allows for tabbing out of the
puzzle into the links below it.
2022-10-25 20:38:37 +01:00
e6faebeb9a js: Remove keypress handler
At least in modern browsers (and I suspect in all browsers), cancelling
a keydown event ensures that the subsequent keypress event doesn't fire.
See <https://w3c.github.io/uievents/#keys-cancelable-keys>.

So there's no point in having a handler on keypress events that just
tries to cancel them as well.  Removing the handler doesn't do much now,
but it opens the possibility of being a bit more selective about which
keydown events we cancel.
2022-10-25 20:13:59 +01:00
43c89dd5e1 js: Add a comment explaining the two halves of the key-matching code 2022-10-25 00:50:47 +01:00
d94d671bf9 js: Handle KeyboardEvent.key == "Spacebar"
This is apparently generated in place of " " by Internet Explorer.
2022-10-25 00:48:58 +01:00
35d382019f js: Recognise KeyboardEvent.key == "Escape" 2022-10-24 23:33:09 +01:00
f5ac13c847 js: Add mapping for UI_REDO based on KeyboardEvent.key 2022-10-24 23:19:56 +01:00
768ef770a3 js: Use KeyboardEvent.key for ASCII keystrokes
This requires passing in KeyboardEvent.location from JavaScript so
that we can detect the numeric keypad properly.  Out of caution we
currently only set MOD_NUM_KEYPAD on numbers, like we always have,
but we have enough information to set it on arrow keys, Enter, "+",
etc.

This finally gets '/' and '\' working in Slant again.
2022-10-24 23:13:33 +01:00
0db5fb525b js: Remove the charCode argument from key()
It hasn't been used in a while.
2022-10-24 22:37:30 +01:00
9698732d65 js: Add modern "key" values for Delete and arrow keys
Firefox has emitted "Delete", "ArrowDown" etc since 2015.
2022-10-24 22:22:33 +01:00
322a439d80 js: Use KeyboardEvent.keyCode and .char only as fallbacks
KeyboardEvent.keyCode is a platform-dependent mess.
KeyboardEvent.char is better-defined, but in my browser it's always
null.  KeyboardEvent.key is the right thing to use when we want to
know the semantics of a key.

This commit just re-organises the big "else if" chain in key() so
that all the tests on "key" come first.  That way at least if key and
keyCode disagree, we'll use the more trustworthy one.
2022-10-24 22:07:12 +01:00
c1059c07fb js: Remove braces from big else-if chain in keyboard handler
If there's ever a case where they're unnecessary noise, it's a long
chain of "else if"s guarding single assignment statements.
2022-10-24 21:57:53 +01:00
a62217e9b4 js: Use less-modern syntax in update_pixel_ratio
Stealing code from the MDN has the consequence that it uses shiny ES6
features like "const", "let", and "=>".  This looks a bit odd among
the more conservative style of the rest of Puzzles, so I've
downgraded it to "var" and "function".  I'll let the template string
stay because that actually helps readability.
2022-10-23 11:15:31 +01:00
0254a163ff js: Make resizing of puzzles work properly again
This requires looking at the CSS size of the puzzle canvas rather than
its internal size, and then adjusting the new size to account for the
device pixel ratio.
2022-10-22 18:50:34 +01:00
989c6defb0 js: Pay attention to changes in device pixel ratio
Because it's the simplest thing to do, when we notice such a change we
keep the current puzzle at its existing size measured in device
pixels.  This has the rather odd consequence that when changing the
text size in Firefox, the size of the puzzle remains constant.
2022-10-22 18:40:01 +01:00
24ce6260d5 js: Pay attention to the device pixel ratio
The CSS "px" unit isn't always a device pixel.  On devices with
high-DPI displays, there can often be multiple device pixels to a CSS
px, while in particularly low-resolution displays (like feature
phones), the user might zoom out to get several CSS px to a device
pixel.  And even on desktop browsers, text zooming controls can change
the ratio.

To make Puzzles' rendering look good on an arbitrary device pixel
ratio, we really want the pixels of the canvas to be device pixels,
not CSS px, so that the canvas doesn't have to be scaled by the
browser for display.  To correct this, we now control the CSS size of
the puzzle canvas, via its containing <div>, to be the canvas size
divided by the device pixel ratio.

There is a significant gap, which is that this doesn't yet track
changes to the device pixel ratio.  This is slightly complicated, so
I'll put it off to the next commit.
2022-10-22 13:55:55 +01:00
9be9a12476 js: Move some styling from style attributes to stylesheet
For consistency as much as anything else.
2022-10-22 13:55:55 +01:00
27f0dafcf0 js: Map mouse co-ordinates correctly even when CSS scales our canvas
Our system for mapping mouse coordinates to canvas coordinates assumed
that the puzzle canvas had the same dimensions in CSS as its own
internal width and height.  This is true in the current wrapper HTML,
but it's very easy to accidentally change and there are circumstances
where we might want to deliberately change it in future.

To fix this, we now inspect the CSS size of the canvas when processing
mouse events, and map the coordinates through the scaling and
translation necessary to convert CSS pixels into canvas pixels.
2022-10-22 13:55:50 +01:00
4feb5fdf0c Update Nikoli links and remove Flash warnings
Most of the old URLs don't work any more.  As far as I can see, the
new pages have no Flash, and even if they did very few browsers will
still support it.
2022-10-22 01:43:51 +01:00
0197ca4359 js: Percent-encode game IDs in URLs and decode them again on input
This is necessary to allow all random seeds to round-trip properly.
It's probably not currently necessary for descriptive game IDs, but it
won't hurt.

I've deliberately gone for encoding only those characters that are not
valid in fragment identifiers to minimise the ugliness of the generated
URLs.  For slightly interesting historical reasons, '#' is not valid in
a fragment identifier, so all random seed links end up a little bit
ugly.
2022-10-21 10:28:01 +01:00
373dadacc0 Build fix: take declarations out of for loops.
The NestedVM build is still unhappy with this C99ism, unfortunately.
2022-10-21 07:52:14 +01:00
a46f0c2ba9 js: Read save files as text rather than binary strings
If I'm going to insist they're text I should be consistent about it.
2022-10-21 00:30:00 +01:00
47905e9547 Revert "WASM: move save file encoding from JS into C."
Now that save files are (even more) officially ASCII, it's perfectly
safe to pass them to JavaScript as UTF-8 strings.

This means that the form in which save files are shipped from C to
JavaScript is the same is the form in which they're shipped from
JavaScript to C.  That allows for doing new things with them, like
writing them to local storage.

This reverts commit f729f51e475ff98d0caf529f0723ef810b1c88ef.
2022-10-21 00:25:34 +01:00
12491021d0 Update comment on parameter string formats in documentation
Net can have non-alphanumeric characters in its parameter strings.  Both
"5x5b0.1" and "5x5b1e-05" are valid parameter strings generated by Net.
So only "most" puzzles use alphanumeric parameter strings.
2022-10-20 23:59:05 +01:00
0ce67c7c3f Document the asserted printable ASCII nature of many strings
The exception is the random seed string, which we lightly document as
non-ASCII.
2022-10-20 23:59:05 +01:00
7f4d038258 Assert that everything written to a save file is printable ASCII
Apart from the newlines of course.
2022-10-20 23:59:05 +01:00
304796f9f1 Hex-encode non-ASCII random seeds in save files
The developer documentation claims that save files are long ASCII
strings.  This is mostly true, but there's nothing stopping a user
from entering non-ASCII characters as random seeds.  The ASCII
property of save files is useful, so encode seeds in hex before
writing them unless they consist only of printable ASCII characters.

Hex-encoded seeds are written under a new key, HEXSEED, to distinguish
them from unencoded seeds.  This means that old versions of the code
won't be able to load encoded seeds, but that's not a great loss:
seeds aren't generally portable between versions anyway.
2022-10-20 23:58:34 +01:00
9f2eef8762 Add assertions that game descriptions consist only of printable ASCII.
That they are ASCII is implied by their inclusion in save files.
Nothing requires an absence of control characters, but it seems polite
to make them slightly readable.
2022-10-20 23:56:43 +01:00
e29d8a3eca Add an assertion to check the format of encoded parameters
Whenever the midend calls encode_params, it also checks that the
result is a printable ASCII string that doesn't contain '#' or ':'.

Parameter strings are embedded in save files, so they have to fit within
ASCII.  They can't contain '#' or ':' because those delimit the
parameter section of a game ID.  Nothing explicitly says they can't
contain control characters, but those would be a particularly egregious
violation of the recommendation that parameter strings be easy to type
into a shell.
2022-10-20 23:54:18 +01:00
dbbe9d3750 js: Make the dialogue box heading actually be an <h2>
This is semantically more correct and less ugly as well.
2022-10-18 01:00:49 +01:00
5c180cfa6f js: When making a hidden element visible, just remove "display: none"
This removes any assumption in the JavaScript code about precisely what
"display" setting the element should have.

This means that now the only places where the JavaScript manipulates
elements' styles are to set the width of the puzzle container and to
mark and unmark elements with "display: none".  These both seem like
reasonable kinds of semantic markup that just happen to be expressed as
styles.
2022-10-17 23:17:59 +01:00
3c3d8aff22 js: Remove unnecessary setting of status bar size
An element with display: block will naturally adjust to fit the width of
its container, so if that's what you want there's no need to set its
width explicitly.
2022-10-17 23:16:35 +01:00
49849e40ec js: Move dialogue-box sizing and positioning from JavaScript to CSS
This has the advantage that if you resize the window while a dialogue
box is active, the dialogue box adjusts itself accordingly.
2022-10-17 23:16:31 +01:00
c90d64f243 js: Move most style settings from JavaScript to CSS
Some elements (generally those created by JavaScript) had their style
parameters set directly by JavaScript.  Putting styles in CSS generally
makes them easier to understand (and fiddle with), so I've done that.
The only styles left in JavaScript are those that are calculated by
JavaScript (like the status-bar size) and the random-seed permalink
visibility because I wasn't quite sure how to handle it.
2022-10-17 22:04:16 +01:00
1bab1d1d2a Correct and enable the range check on statepos when loading
statepos == 0 shouldn't ever occur in a save file because it indicates
an uninitialised midend.  OTOH statepos == nstates is normal.  Also
added an equivalent assertion when saving because Simon and I spent
some time discussing whether it could happen.
2022-10-16 19:15:40 +01:00
02e5e93046 Add more validation to midend deserialisation routine
These are all pretty obvious and enforce constraints that would
otherwise be enforced by segfault.
2022-10-16 19:02:14 +01:00
879a6922b0 js: Update permalinks and undo/redo buttons when loading
Without this, the "Undo" button ends up greyed even though it actually
works.  I'm not sure about whether updating the permalinks is necessary:
maybe we don't need that in new_game() either.
2022-10-15 18:23:15 +01:00
f11e93e3bd js: Update comment on possible future enhancements
Load/save has been in the JavaScript backend for a while, as have
prettier controls.  And JavaScript-capable touchscreens are all around
us, if still poorly supported by Puzzles.
2022-10-13 10:07:05 +01:00
a11a5726b2 Add a missing "const" to js_draw_poly and js_canvas_draw_poly 2022-10-13 00:13:00 +01:00
85d2a7da62 Hide some words in top-level menu items on small viewports
In their normal state, most of the top-level menu items are a verb and
an object, like "Undo move".  This is admirably clear, but on a small
screen the menu can take a lot of space.  In each case the verb alone
is sufficient to know what the button does, so use a media query to
suppress the noun is the viewport is very narrow.  "Very narrow" here
is roughly where the menus would overflow onto four lines in my
browser.
2022-10-07 17:55:06 +01:00
e98ede7a72 Make JavaScript game controls work better in small viewports
In the old design, when they wrapped onto multiple lines, various bad
things happened.  The lines overlapped one another, the lines got
broken within buttons but not between buttons, and if they had got
broken between buttons the left button on each line would have lacked
a left border.

I've made two major changes to fix this.  First, I've switched from
flow layout to flex layout.  This has much better default behaviour,
breaking lines in the right places, not overlapping lines, and even
arranging line-wrapping within a button when the viewport gets really
narrow.

Second, I've given each button a border on all four sides and then
used negative margins to overlap them.  This required changing the
borders from transparent black to opaque grey to make them display
correctly when overlapping.

The result is not quite identical to the old version on a wide
viewport, but I think it's as close as I can get while keeping the new
CSS pleasant.

Ideally, the separator would vanish when it was adjacent to a line
break, but I've not worked out how to do that yet.
2022-10-05 12:52:03 +01:00
27dd36e3e6 Enable Apple Silicon in the MacOS builds. 2022-09-12 11:01:40 +01:00
9c13279938 unix, gtk: Install and use HTML help
- Generate HTML pages from the manual, and install them
- Add "Contents" and "Help on <name>" menu items that will open the
  appropriate page in a web browser
2022-08-01 18:41:10 +01:00