aboutsummaryrefslogtreecommitdiff
path: root/emcc.c (follow)
Commit message (Collapse)AuthorAge
* Remove a comment suggesting use of localStorage for prefsBen Harris2023-08-21
| | | | | Preferences in the JavaScript version _are_ stored in localStorage now.
* js: keep colour strings in JavaScript rather than in CBen Harris2023-07-30
| | | | | | | | | | | | | | | 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.
* js: Copy-to-clipboard supportBen Harris2023-07-05
| | | | | | | | | | | | | | 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 <canvas> while Chromium targets the <body>. 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.
* Expose the NO_EFFECT/UNUSED distinction through midend_process_key()Ben Harris2023-06-11
| | | | | | | | | | | | | | | | | | | | | | 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 -> PKR_SOME_EFFECT MOVE_UI_UPDATE -> PKR_SOME_EFFECT MOVE_NO_EFFECT -> PKR_NO_EFFECT MOVE_UNUSED -> 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.
* Support user preferences in the Emscripten frontend.Simon Tatham2023-04-24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* emcc.c: remove savefile_read_ctx.Simon Tatham2023-04-24
| | | | | | 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.
* emcc.c: missing (void) in a function definition.Simon Tatham2023-04-24
| | | | This isn't C++, ahem.
* js: Load save files into the C side incrementallyBen Harris2023-04-03
| | | | | | | | | | | | | | | | | | | | | | | | | 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.
* New shared function, getenv_bool()Ben Harris2023-03-22
| | | | | | | | | | | | | 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.
* More cleverness in midend_process_key()Ben Harris2023-02-23
| | | | | | | | | | | 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.
* Convert a lot of floating-point constants to single precisionBen Harris2023-02-19
| | | | | | | | | | | | | | | | | | For reasons now lost to history, Puzzles generally uses single-precision floating point. However, C floating-point constants are by default double-precision, and if they're then operated on along with a single-precision variable the value of the variable gets promoted to double precision, then the operation gets done, and then often the result gets converted back to single precision again. This is obviously silly, so I've used Clang's "-Wdouble-promotion" to find instances of this and mark the constants as single-precision as well. This is a bit awkward for PI, which ends up with a cast. Maybe there should be a PIF, or maybe PI should just be single-precision. This doesn't eliminate all warnings from -Wdouble-promotion. Some of the others might merit fixing but adding explicit casts to double just to shut the compiler up would be going too far, I feel.
* Make emcc.c clean under -Wmissing-prototypes etcBen Harris2023-02-18
| | | | | | | | Also -Wstrict-prototypes and -Wmissing-variable-declarations. Functions that are called from JavaScript now have a separate declaration at the top of the file with a comment reminding one to update emcclib.js if they're changed.
* js: Hide type menu if there's only one preset and no configurationBen Harris2023-02-16
| | | | It seems a bit silly to display it when there's only one option.
* kaios: Hack out everything that needs dialogue boxesBen Harris2023-01-19
| | | | | | | | | | | | | They're proving to be a right nuisance and will probably require a substantial overhaul to how they work across the entire JavaScript front-end. I don't think any of the functionality provided by the dialogue boxes is critical, so in the interests of getting a minimum viable product actually released I've disabled those features. In most cases, this just involves commenting out bits of HTML. The "Custom..." menu item is added by C code, though, so there I've fallen back to the standard Puzzles way to implement a nasty hack: an environment variable.
* js: Remove an outdated reference to the "invisible Custom option"Ben Harris2023-01-19
|
* js: Simpler and more robust startup procedureBen Harris2023-01-19
| | | | | | | | | | | | | | | Previously, we initialised all of the JavaScript event handlers as soon at the DOM was loaded, and then called main() ourselves once the Emscripten runtime was ready. This was slightly dangerous since it depended on none of those event handlers' being called before main(). In practice this was difficult because most of the elements the event handlers were attached to were invisible, but it did limit what event handlers could safely be used. Now, the event handlers are initialised from main(). This makes things work in a sufficiently conventional way that we can just let the Emscripten run-time call main() in its usual way, rather than involving ourselves in the minutiae of Emscripten's startup.
* js: Use current_key_label() to label feature phone softkeysBen Harris2023-01-19
|
* js: Rename update_undo_redo() as post_move()Ben Harris2023-01-19
| | | | I want to do more things with it.
* js: Don't treat SoftRight as CURSOR_SELECT2Ben Harris2022-12-10
| | | | | | I was hoping that I could treat SoftLeft and SoftRight the same in C and arrange to filter one of them out in JavaScript, but that turned out to be impractical.
* js: Add a new function whereby C can ask JS for a preferred board sizeBen Harris2022-12-10
| | | | Currently JS has no opinion.
* js: Set the default colour from the CSS background of the canvasBen Harris2022-12-10
| | | | | | | This allows the HTML/CSS to decide that it would like a different background colour without the need to recompile. The default if the CSS specifies no colour (and hence the canvas is transparent) is the same grey as before.
* js: Allow CSS to set the font used by the puzzleBen Harris2022-12-10
| | | | | | | | | | | | | | This means that the calculated font properties of the HTML canvas now control what font is used. The size is overridden, and for monospaced text so is the family. I'd like to be able to also specify the monospaced font, maybe using a CSS variable, but that looks like being quite a lot of extra complexity. My experience when testing this was that constructing a valid "font" string for a canvas context is prone to breakage, but broke in a way that left the font unchanged, so we always set a simple specification first before trying to construct one from CSS.
* js: Put the puzzle background colour in a CSS variableBen Harris2022-12-05
| | | | | | | | | It's sometimes useful to be able to have an HTML element that visually forms an extension of the puzzle's border. By putting the puzzle's colour 0 (which we assume to be its background) into a CSS variable, such elements can do something like "background-color: var(--puzzle-background)" to get that effect even if the puzzle uses a non-default background colour.
* js: Remove support for creating the status bar in JavaScriptBen Harris2022-11-28
| | | | Now we depend on its being in the HTML.
* js: More conventional marking of menu item typesBen Harris2022-11-24
| | | | | | | | | | Menu items that open dialogue boxes are now marked with ellipses, while menu items that lead to submenus have pointing triangles. The triangles are implemented as SVG files embedded in data: URLs in the CSS, which is kind of silly but also works really well. There are suitable characters in Unicode, but some of my test systems don't have fonts containing them, so maybe the SVG is better.
* js: Allow status bar to be present in the HTMLBen Harris2022-11-20
| | | | | | | I'm generally in favour of putting HTML in HTML rather the constructing it in JavaScript, and this will allow for simplifying the code eventually. This only changes the JavaScript to make sure that's in people's caches before I change the HTML itself.
* js: Better handling of games without presets and/or solveBen Harris2022-11-13
| | | | | | | | | | | | | | | | | | Games with neither presets nor configuration (which may only be the Null Game) have been slightly broken since the introduction of hierarchical preset menus, in that the code to remove the "Type..." menu stopped being called then. My switch to using radio buttons in menus then broke them utterly because it's not possible to set the value of an empty radio group, causing a crash at startup. Fix this by detected when there's no preset menu, removing the item from the menu bar, and setting the variable that's meant to indicate this has been done. The solve button problem was more subtle, in that only the <button> was being hidden and not the <li> containing it, which led to the right border of the menu bar being two pixels thick. Switch to fully removing the <li> from the DOM, like we now do with the presets menu, since that also makes my keyboard handler (in another branch) simpler.
* js: Cancel UI events when the mid end says they've been handledBen Harris2022-11-08
| | | | | This means that if a key doesn't do anything in a puzzle, it can operate the browser instead.
* Add a way for midend_process_key() to report whether it handled a keypressBen Harris2022-11-08
| | | | | | | | This adds a new bool * argument, which can be NULL if front ends don't care whether the keypress was handled. Currently they all do that. Currently, "undo" and "redo" keys are treated as not handled if there's no move to undo or redo. This may be a little too strict.
* js: Make SoftRight act as CURSOR_SELECT2 as wellBen Harris2022-11-08
| | | | | | This way, the front end can intercept one of SoftLeft and SoftRight as a menu key and leave the other one for the puzzle. And while we don't have a working menu, I can use whichever is more convenient.
* js: Map the "SoftLeft" key to CURSOR_SELECT2Ben Harris2022-11-08
| | | | | | This is the left soft key on KaiOS phones. The centre soft key already sends "Enter", which eventually becomes CURSOR_SELECT. The right soft key I'm planning to use to open the menu.
* js: Move much of the handling of device pixel ratios to the mid-endBen Harris2022-11-08
| | | | | Now that the mid-end knows how to do it, we can remove some complexity from the front end.
* Teach the mid-end about device pixel ratiosBen Harris2022-11-08
| | | | | | | | | | | | | | The device pixel ratio indicates how many physical pixels there are in the platonic ideal of a pixel, at least approximately. In Web browsers, the device pixel ratio is used to represent "retina" displays with particularly high pixel densities, and also to reflect user-driven zooming of the page to different text sizes. The mid-end uses the device pixel ratio to adjust the tile size at startup, and can also respond to changes in device pixel ratio by adjusting the time size later. This is accomplished through a new argument to midend_size() which can simply be passed as 1.0 in any front end that doesn't care about this.
* js: Take device pixel ratio into account when setting default sizeBen Harris2022-10-27
| | | | | | | | | | | | | | 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.
* js: Distinguish manual resizes from device pixel ratio changesBen Harris2022-10-27
| | | | | | | | | | 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.
* js: Split setting nominal and actual canvas sizeBen Harris2022-10-27
| | | | | 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.
* js: Be more subtle about cancelling keydown eventsBen Harris2022-10-25
| | | | | | | | | 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.
* js: Add a comment explaining the two halves of the key-matching codeBen Harris2022-10-25
|
* js: Handle KeyboardEvent.key == "Spacebar"Ben Harris2022-10-25
| | | | This is apparently generated in place of " " by Internet Explorer.
* js: Recognise KeyboardEvent.key == "Escape"Ben Harris2022-10-24
|
* js: Add mapping for UI_REDO based on KeyboardEvent.keyBen Harris2022-10-24
|
* js: Use KeyboardEvent.key for ASCII keystrokesBen Harris2022-10-24
| | | | | | | | | | 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.
* js: Remove the charCode argument from key()Ben Harris2022-10-24
| | | | It hasn't been used in a while.
* js: Add modern "key" values for Delete and arrow keysBen Harris2022-10-24
| | | | Firefox has emitted "Delete", "ArrowDown" etc since 2015.
* js: Use KeyboardEvent.keyCode and .char only as fallbacksBen Harris2022-10-24
| | | | | | | | | | | 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.
* js: Remove braces from big else-if chain in keyboard handlerBen Harris2022-10-24
| | | | | If there's ever a case where they're unnecessary noise, it's a long chain of "else if"s guarding single assignment statements.
* Revert "WASM: move save file encoding from JS into C."Ben Harris2022-10-21
| | | | | | | | | | | | 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.
* js: Update permalinks and undo/redo buttons when loadingBen Harris2022-10-15
| | | | | | 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.
* js: Update comment on possible future enhancementsBen Harris2022-10-13
| | | | | | 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.
* Add a missing "const" to js_draw_poly and js_canvas_draw_polyBen Harris2022-10-13
|