aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAge
...
* GTK save_prefs: fix a wrongly sourced error report.Simon Tatham2023-04-24
| | | | | | 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.
* Slant: actually check ui->swap_buttons.Simon Tatham2023-04-23
| | | | | | 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.
* GTK: stop referring to &thegame in prefs I/O functions.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | 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.
* Support user preferences on Windows.Simon Tatham2023-04-23
| | | | | This is done using basically the same methods as on Unix, and just translating the system calls in save_prefs to a different API.
* make_prefs_path(): tolerate NULL inputs.Simon Tatham2023-04-23
| | | | | | | | 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.
* Document the new Net preference.Simon Tatham2023-04-23
| | | | Naturally, I only remembered to do this after 'git push'.
* Net: preference for how loop highlighting interacts with locking.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | 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.
* Fix failure to update me->ui when changing preferences.Simon Tatham2023-04-23
| | | | | | | | | 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.
* GTK: add a command-line --delete-prefs option.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | 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.)
* Support preferences in the GTK frontend.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | | | 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.
* Universal preference option for one-key shortcuts.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Keep a set of preferences in the midend.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Require games to accept new_ui(NULL) if they have preferences.Simon Tatham2023-04-23
| | | | | | | | | | | 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.
* Generalise the midend serialisation callbacks.Simon Tatham2023-04-23
| | | | | | | | | 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.
* New backend functions: get_prefs and set_prefs.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | | | | | | | | 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.
* Move per-puzzle ad-hoc getenv preferences into game_ui.Simon Tatham2023-04-23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* Pass a game_ui to compute_size, print_size and print.Simon Tatham2023-04-21
| | | | | | | 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.
* Missing const in configure() documentation.Simon Tatham2023-04-21
| | | | | Commit de67801b0fd3dfa changed the 'name' field from char * to const char *, but didn't update the docs to match. Better late than never.
* Filling: switch to using dsf_minimal in minimize_clue_set.Simon Tatham2023-04-21
| | | | | | | | | 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.
* Loopy: draw even faint lines using draw_thick_line.Simon Tatham2023-04-20
| | | | | | | | | | | | | 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.
* Turn off Leak Sanitiser in the icons build.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | | | | 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.
* Update the documentation for the dsf functions.Simon Tatham2023-04-20
| | | | Easier to do this all in one go after I've finished messing about.
* Actually rewrite the dsf implementation.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | | | | | This rewrite improves the core data structure implementation in two ways. Firstly, when merging two equivalence classes, we check their relative sizes, and choose the larger class's canonical element to be the overall root of the new class tree. This minimises the number of overlong paths to the root after the merge. Secondly, we defer path compression until _after_ the two classes are merged, rather than do it beforehand (via using edsf_canonify as a subroutine) and then have to do it wastefully again afterwards. The size-based root selection was what we _used_ to do, and delivers the better asymptotic performance. I reverted it so that Keen could track the min of each equivalence class. But since then I've realised you can have the asymptotic goodness _and_ min-tracking if you store the minima separately from the main data structure. So now Keen does that, and other clients don't have to pay the cost. Similarly, the flip tracking is now a cost that only users of flip dsfs have to pay, because a normal one doesn't store that information at all.
* Reorganise the dsf API into three kinds of dsf.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | This is preparing to separate out the auxiliary functionality, and perhaps leave space for making more of it in future. The previous name 'edsf' was too vague: the 'e' stood for 'extended', and didn't say anything about _how_ it was extended. It's now called a 'flip dsf', since it tracks whether elements in the same class are flipped relative to each other. More importantly, clients that are going to use the flip tracking must say so when they allocate the dsf. And Keen's need to track the minimal element of an equivalence class is going to become a non-default feature, so there needs to be a new kind of dsf that specially tracks those, and Keen will have to call it. While I'm here, I've renamed the three dsf creation functions so that they start with 'dsf_' like all the rest of the dsf API.
* Introduce a new dsf_equivalent() function.Simon Tatham2023-04-20
| | | | | Not very interesting, but the idiom for checking equivalence via two calls to dsf_canonify is cumbersome enough to be worth abbreviating.
* Remove conditioned-out dsf diagnostic code.Simon Tatham2023-04-20
| | | | | | | | print_dsf was declared in puzzles.h, but never called, and its definition was commented out. So it probably wouldn't still have worked anyway. The other commented-out printfs in that file don't look very useful either, and they just mean more stuff will need messing about with as I continue to refactor.
* Remove size parameter from dsf init and copy functions.Simon Tatham2023-04-20
| | | | | | | | | Now that the dsf knows its own size internally, there's no need to tell it again when one is copied or reinitialised. This makes dsf_init much more about *re*initialising a dsf, since now dsfs are always allocated using a function that will initialise them anyway. So I think it deserves a rename.
* Store a size field inside the DSF type.Simon Tatham2023-04-20
| | | | | | This permits bounds-checking of all inputs to dsf_canonify and dsf_merge, so that any out-of-range values will provoke assertion failure instead of undefined behaviour.
* Actually make DSF an opaque structure type.Simon Tatham2023-04-20
| | | | | | | | | | This makes good on all the previous preparatory commits, which I did separately so that each one individually has a reasonably readable diff, and all the mechanical changes are separated out from the rewrites that needed actual thought. Still no functional change, however: the DSF type wraps nothing but the same int pointer that 'DSF *' used to store directly.
* Declare all dsfs as a dedicated type name 'DSF'.Simon Tatham2023-04-20
| | | | | | | In this commit, 'DSF' is simply a typedef for 'int', so that the new declaration form 'DSF *' translates to the same type 'int *' that dsfs have always had. So all we're doing here is mechanically changing type declarations throughout the code.
* Remove a direct use of dsf internals in Filling.Simon Tatham2023-04-20
| | | | | The expression 'dsf[foo] >> 2' already has a sensible wrapper function, but Filling wasn't bothering to call it.
* Consistently use snew_dsf to allocate dsfs.Simon Tatham2023-04-20
| | | | | All remaining cases where a dsf was allocated via snewn(foo, int) are removed by this change.
* Use a dedicated copy function to copy dsfs.Simon Tatham2023-04-20
| | | | | | | | | Previously we were duplicating the contents of a dsf using straight-up memcpy. Now there's a dsf_copy function wrapping the same memcpy. For the moment, this still has to take a size parameter, because the size isn't stored inside the dsf itself. But once we make a proper data type, it will be.
* Use a dedicated free function to free dsfs.Simon Tatham2023-04-20
| | | | | No functional change: currently, this just wraps the previous sfree call.
* Stop putting dsfs in existing scratch int arrays.Simon Tatham2023-04-20
| | | | | | | | | | | | | | | | | | | | | | | I'm going to work towards turning 'dsf' into an opaque type, so that I can improve its implementation without breaking clients. The first step is to deal manually with puzzles that currently reuse a single array of ints for multiple purposes, some of which are dsf and some are not. In divvy_rectangle_attempt, 'tmp' was used as an int array and later a dsf, and I've made a new 'tmpdsf' to be the latter. In Dominosa, solver->pc_scratch2 was sometimes a dsf, and now there's a new solver->dsf_scratch. In Map, parse_edge_list() needed a dsf internally and then never exported it; it expected to be passed an array of 2*w*h ints and used the second half as a dsf. Now it expects only w*h ints, and allocates its own dsf internally, freeing it again before returning. And in Tents, find_errors() was allocating a single block of 2*w*h ints and using the second half of it as a dsf, apparently just to save one malloc. Now we malloc and free the dsf separately.
* Remove an unnecessary extern function declaration.Simon Tatham2023-04-20
| | | | | | | unfinished/separate.c had its own declaration of divvy_rectangle(), duplicating the one in puzzles.h. Probably that was where the declaration originally lived, before I moved it out into the main header.
* Move obfuscator tests into obfusc.c.Simon Tatham2023-04-16
| | | | | | | | I just found these self-tests lying around in mines.c under an #ifdef that nobody ever enables. Let's put them somewhere more sensible! We already have a separate tool for working with the obfuscation system in a puzzle-independent way, and it seems reasonable to put them in there.
* Reference my just-published article about aperiodic tilings.Simon Tatham2023-04-10
| | | | | | | | | | | | | | | | | | | In commit 8d6647548f7d005 I added the Hats grid type to Loopy, and mentioned in the commit message that I was very pleased with the algorithm I came up with. In fact, I was so pleased with it that I've decided it deserves a proper public writeup. So I've spent the Easter weekend producing one: https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/aperiodic-tilings/ In this commit I adjust the header comments in both penrose.c and hat.c to refer to the article (replacing a previous comment in penrose.c to a much less polished page containing a copy of my jotting-grade personal notes that I sent James Harvey once). Also, added some code to hatgen.c to output Python hat descriptions in a similar style to hat-test, which I used to generate a couple of the more difficult diagrams in the new article, and didn't want to lose.
* Don't allow zero clues in PatternBen Harris2023-04-08
| | | | | | | | | | | | | | Some nonogram implementations allow zero clues so that a row or column with a single zero clue is equivalent to one with no clues, that is it has no black squares in it. Pattern, however, doesn't interpret them like this and treats a puzzle with a zero clue as insoluble, so it's not helpful to permit them. Permitting zero clues also confuses Pattern's memory allocation so that it can suffer a buffer overrun. As an example, before this commit a build with AddressSanitizer would report a buffer overrun with the description "1:0/0.0" because it tries to put two clues in a row that can have a maximum of one.
* Net: validate co-ordinates in decode_ui()Ben Harris2023-04-08
| | | | | | | | | | | | | | | | The offset and centre location should be within the grid. Otherwise the redraw code will suffer an assertion failure. This save file demonstrates the problem: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection VERSION :1:1 GAME :3:Net PARAMS :4:5x5w CPARAMS :4:5x5w DESC :25:9893e85285bb72e6de5182741 UI :9:O0,0;C6,6 NSTATES :1:1 STATEPOS:1:1
* Add a game_state argument to decode_ui()Ben Harris2023-04-08
| | | | | | | | Some games would like a way to check that the parameters in the encoded UI string are consistent with the game parameters. Since this might depend on the current state of the game (this being what changed_state() is for), implement this by adding a game_state parameter to decode_ui(). Nothing currently uses it, though Guess usefully could.
* Make encode_ui() and decode_ui() optional in back-endsBen Harris2023-04-08
| | | | | | | | | | | | The majority of back-ends define encode_ui() to return NULL and decode_ui() to do nothing. This commit allows them to instead specify the relevant function pointers as NULL, in which case the mid-end won't try to call them. I'm planning to add a parameter to decode_ui(), and if I'm going to have to touch every back-end's version of decode_ui(), I may as well ensure that most of them never need to be touched again. And obviously encode_ui() should go the same way for symmetry.
* Net: assert that cx and cy are in range in compute_active()Ben Harris2023-04-08
| | | | | | | | | | | | | | | | | | | This avoids an out-of-range heap write shortly afterwards. An assertion failure is better than a buffer overrun, but still not ideal. Fixing the problem properly will require fairly wide-ranging changes, though. The bug can be demonstrated by loading this save file into a build with AddressSanitizer: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection VERSION :1:1 GAME :3:Net PARAMS :4:5x5w CPARAMS :4:5x5w DESC :25:9893e85285bb72e6de5182741 UI :9:O0,0;C6,6 NSTATES :1:1 STATEPOS:1:1
* js: explicitly tell Emscripten which browsers to targetBen Harris2023-04-06
| | | | | | | | | | | | | | | Emscripten has settings indicating which browser versions it should build code for. These are now by default slightly newer than I'd been targeting with my hand-written JavaScript. They also don't include Firefox 48, which KaiOS 2.5 is based on. This commit adds CMake variables to set the minimum versions that we pass to Emscripten. They default to the earliest versions with WebAssembly support, except that Firefox 48 is also supported. I think the main consequence of this change is to stop Emscripten using sign-extension and mutable-globals in WebAssembly, which it's done by default since version 3.1.26.
* js: set -s ENVIRONMENT=web in EmscriptenBen Harris2023-04-06
| | | | | | Puzzles only runs in Web browsers, so there's no need to include support for Node or (for now at least) running in a Web worker. This removes about 5 kiB of code from the boilerplate JavaScript.
* Fall back to <math.h> if <tgmath.h> doesn't work.Simon Tatham2023-04-06
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This fixes a build failure introduced by commit 2e48ce132e011e8 yesterday. When I saw that commit I expected the most likely problem would be in the NestedVM build, which is currently the thing with the most most out-of-date C implementation. And indeed the NestedVM toolchain doesn't have <tgmath.h> - but much more surprisingly, our _Windows_ builds failed too, with a compile error inside <tgmath.h> itself! I haven't looked closely into the problem yet. Our Windows builds are done with clang, which comes with its own <tgmath.h> superseding the standard Windows one. So you'd _hope_ that clang could make sense of its own header! But perhaps the problem is that this is an unusual compile mode and hasn't been tested. My fix is to simply add a cmake check for <tgmath.h> - which doesn't just check the file's existence, it actually tries compiling a file that #includes it, so it will detect 'file exists but is mysteriously broken' just as easily as 'not there at all'. So this makes the builds start working again, precisely on Ben's theory of opportunistically using <tgmath.h> where possible and falling back to <math.h> otherwise. It looks ugly, though! I'm half tempted to make a new header file whose job is to include a standard set of system headers, just so that that nasty #ifdef doesn't have to sit at the top of almost all the source files. But for the moment this at least gets the build working again.
* Remove obsolete testbuild.c.Simon Tatham2023-04-06
| | | | | | | | | It was originally used for probing the available warning flags in the compiler, by adding them one by one and making sure this test file still compiled. But that whole mechanism was removed in commit 306fab356e357ef, and since then, testbuild.c has been unused. Belatedly throw it away.
* KaiOS: include extra copyright notices in manualBen Harris2023-04-06
| | | | | | | | | | | | | | | | The KaiOS build includes compiled versions of various Emscripten library files. These are generally under the MIT licence like Puzzles itself. The MIT licence requires that the licence, and the copyright notice, be "included in all copies or substantial portions of the Software." Since each KaiOS package includes the full manual, which already contains the licence for Puzzles itself, adding the copyright notices there seems like the best approach. I've done this by providing an additional input file that contains the licences for source files used by a current Emscripten build. More automation might be nice, but the set of copyright notices is unlikely to change very much. There are basically one for Emscripten, one for musl, and a few for odd bits of third-party code embedded in musl.
* Replace <math.h> with <tgmath.h> throughoutBen Harris2023-04-04
| | | | | | | | | | | | | | | C89 provided only double-precision mathematical functions (sin() etc), and so despite using single-precision elsewhere, those are what Puzzles has traditionally used. C99 introduced single-precision equivalents (sinf() etc), and I hope it's been long enough that we can safely use them. Maybe they'll even be faster. Rather than directly use the single-precision functions, though, we use the magic macros from <tgmath.h> that automatically choose the precision of mathematical functions based on their arguments. This has the advantage that we only need to change which header we include, and thus that we can switch back again if some platform has trouble with the new header.
* js: stop using EXTRA_EXPORTED_RUNTIME_METHODSBen Harris2023-04-03
| | | | | Current Emscripten has deprecated it in favour of EXPORTED_RUNTIME_METHODS, and using that avoids generating warnings.