aboutsummaryrefslogtreecommitdiff
path: root/emccpre.js (follow)
Commit message (Collapse)AuthorAge
* WASM: move save file encoding from JS into C.Simon Tatham2021-05-23
| | | | | | | | | | | | | | | | | | | | | | | | | | The previous fix worked OK, but it was conceptually wrong. Puzzles save files are better regarded as binary, not text: the length fields are measured in bytes, so translating the file into a different multibyte character encoding would invalidate them. So it was wrong to fetch a C byte string containing the exactly right binary data, then translate it into a Javascript string as if decoding from UTF-8, then retranslate to a representation of a bytewise encoding via encodeURIComponent, and then label the result as application/octet-stream. This probably wouldn't have caused any problems in practice, because I don't remember any situation in which my save files use characters outside printable ASCII (plus newline). But it's not actually forbidden, so a save file might choose to do that some day, so that UTF-8 decode/reencode hidden in the JS was a latent bug. Now the URI-encoding is done on the C side, while we still know exactly what the binary data ought to look like and can be sure we're translating it byte for byte into the output encoding for the data: URI. By the time the JS receives a string pointer from get_save_file, it's already URI-encoded, which _guarantees_ that it's in ASCII and won't be messed about with by Emscripten's UTF8ToString.
* WASM: fix save-file generation.Simon Tatham2021-05-22
| | | | | | | | In commit f6434e84964d840 I said I had replaced all uses of old-Emscripten's Pointer_stringify() function with new-Emscripten's UTF8ToString(). In fact, I only replaced the ones in emcclib.js, but I missed one in emccpre.js used in preparing downloadable save files. Those were therefore broken, with a Javascript undefined-name error.
* wasm/js/emscripten: Fix page loading raceIan Jackson2021-04-22
| | | | | | | | | | | | | | | | Using a stunt webserver which artificially introduces a 3s delay just before the last line of the HTML output, I have reproduced a uwer-reported loading/startup race bug: Previously the wasm loading was started by the <script> element, synchronously. If the wasm loading is fast, and finishes before the HTML loading, the onRuntimeInitialized event may occur before initPuzzles. But initPuzzles sets up the event handler. Fix this bug, and introduce a new comment containing an argument for the correctness of the new approach. Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
* Update web puzzles to current WASM-based Emscripten.Simon Tatham2021-04-03
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I presume this will improve performance. Also, if I've understood correctly, WASM-based compiled web code is capable of automatically growing its memory, which the previous asm.js build of the puzzles could not do, and occasionally caused people to complain that if they tried to play a _really big_ game in their browser, the JS would eventually freeze because the emulated memory ran out. I've been putting off doing this for ages because my previous Emscripten build setup was so finicky that I didn't like to meddle with it. But now that the new cmake system in this source tree makes things generally easier, and particularly since I've just found out that the up-to-date Emscripten is available as a Docker image (namely "emscripten/emsdk"), this seemed like a good moment to give it a try. The source and build changes required for this update weren't too onerous. I was half expecting a huge API upheaval, and indeed there was _some_ change, but very little: - in the JS initPuzzle function, move the call to Module.callMain() into Module.onRuntimeInitialized instead of doing it at the top level, because New Emscripten's .js output likes to load the accompanying .wasm file asynchronously, so you can't call the WASM main() until it actually exists. - in the JS-side library code, replace all uses of Emscripten's Pointer_stringify() function with the new name UTF8ToString(). (The new version also has an ASCIIToString(), so I guess the reason for the name change is that now you get to choose which character set you meant. I need to use UTF-8, so that the × and ÷ signs in Keen will work.) - set EXTRA_EXPORTED_RUNTIME_METHODS=[cwrap,callMain] on the emcc link command line, otherwise they aren't available for my JS setup code to call. - (removed -s ASM_JS=1 from the link options, though I'm not actually sure it made any difference one way or the other in the new WASM world) - be prepared for a set of .wasm files to show up as build products alongside the .js ones. - stop building with -DCMAKE_BUILD_TYPE=Release! I'm not sure why that was needed, but if I leave that flag on my cmake command line, the output .js file fails to embed my emccpre.js, so the initial call to initPuzzle() fails from the HTML wrapper page, meaning nothing at all happens.
* Javascript frontend: make Shift- and Ctrl-click work.Simon Tatham2019-04-12
| | | | | | In other front ends, Shift-click is an alternative to the middle button, and Ctrl-click the right button. Apparently I completely forgot to implement this in the JS front end. Better late than never.
* Support for loading games in Javascript puzzles.Simon Tatham2017-09-05
| | | | | | | | | | | This is done by showing a dialog containing an <input type="file"> through which the user can 'upload' a save file - though, of course, the 'upload' doesn't go to any HTTP server, but only into the mind of the Javascript running in the same browser. It would be even nicer to support drag-and-drop as an alternative UI for getting the save file into the browser, but that isn't critical to getting the first version of this feature out of the door.
* Support for saving games in Javascript puzzles.Simon Tatham2017-09-05
| | | | | | | | | This is done by getting midend_serialise to produce the complete saved-game file as an in-memory string buffer, and then encoding that into a data: URI which we provide to the user as a hyperlink in a dialog box. The hyperlink has the 'download' attribute, which means clicking on it should automatically offer to save the file, and also lets me specify a not-too-silly default file name.
* Factor some HTML dialog functions out of emcclib.Simon Tatham2017-09-05
| | | | | | | | | | | | | | I'm about to want to call these from Javascript as well as from Emscripten-compiled C, so I need versions of them that aren't wrapped up in the Emscripten library object and also don't expect half their parameters to be Emscripten-verse char pointers requiring calls to Pointer_stringify. The easiest way to achieve all of that is to turn the Emscripten- ready versions of those functions in emcclib.js into tiny wrappers around the JS versions, which do the pointer stringification and a couple of other details like directing callbacks to the right C functions.
* Rework the preset menu system to permit submenus.Simon Tatham2017-04-26
| | | | | | | | | | | | | | | | | | | | To do this, I've completely replaced the API between mid-end and front end, so any downstream front end maintainers will have to do some rewriting of their own (sorry). I've done the necessary work in all five of the front ends I keep in-tree here - Windows, GTK, OS X, Javascript/Emscripten, and Java/NestedVM - and I've done it in various different styles (as each front end found most convenient), so that should provide a variety of sample code to show downstreams how, if they should need it. I've left in the old puzzle back-end API function to return a flat list of presets, so for the moment, all the puzzle backends are unchanged apart from an extra null pointer appearing in their top-level game structure. In a future commit I'll actually use the new feature in a puzzle; perhaps in the further future it might make sense to migrate all the puzzles to the new API and stop providing back ends with two alternative ways of doing things, but this seemed like enough upheaval for one day.
* Javascript puzzles: switch to a CSS-based drop-down system.Simon Tatham2017-04-26
| | | | | | | | | | | | | | | The previous control buttons and dropdowns based on form elements were always a bit ugly: partly in a purely visual sense, and partly because of the nasty bodge I had to do with splitting the usual 'Custom' game type menu item into two (to get round the fact that if an element of a <select> is already selected, browsers won't send an event when it's re-selected). Also, I'm about to want to introduce hierarchical submenus in the Type menu, and <select> doesn't support that at all. So here's a replacement system which does everything by CSS properties, including the popping-up of menus when the mouse moves over their parent menu item. (Thanks to the Internet in general for showing me how that trick is done.)
* emcc frontend: stop indiscriminately squashing mouseups.Simon Tatham2015-08-14
| | | | | | | | | | | | | | | The mouseup listener was calling event.preventDefault(), as part of the mechanism for making mouse clicks and drags on the puzzle's resize handle have resizing effects _instead_ of the normal browser behaviour. However, calling event.preventDefault() on _every_ mouseup, rather than just the ones associated with the resize handle, was overkill, and I've recently noticed that it's breaking attempts to select from the game type dropdown by clicking the mouse. So now I'm only calling preventDefault() on the mouseups that I have reason to think are actually relevant to what I'm trying to do. (I don't know why I've only just noticed this. I suppose a change of behaviour between Firefox versions is the most likely cause.)
* Change our method of calling main() in emccpre.js.Simon Tatham2014-04-20
| | | | | | | | | | | I've just upgraded to emcc 1.16.0, in which something fiddly has happened to the semantics of Module.run() vs noInitialRun - now setting the latter seems to cause the former to do everything except calling main(), and then refuse to ever do anything again. So now I have to use Module.callMain() in place of Module.run() when I finally do get round to wanting to call main(). [originally from svn r10180]
* Add a draggable resize handle to the JS puzzles.Simon Tatham2013-04-07
| | | | | | | | | | | | | | | | | | | | | | | Rather than design an ersatz 'window frame' surrounding the puzzle canvas, I've simply overlaid the resize handle on the corner of the puzzle itself (canvas or status bar, depending on whether the latter exists), trusting that all games in my collection provide a reasonable border within their drawing area. (OS X already does this with its resize handle, so it's not as if there's no precedent.) Unlike the desktop versions, I control the resize behaviour completely in this environment, so I can constrain the canvas to only ever be sensible sizes with no dead space round the edges (and, in particular, preserve the aspect ratio). Right-clicking the resize handle will restore the puzzle's default tile size. I had intended to implement a maximise-to-browser-window button too, but was annoyingly foiled by scrollbars - if you maximise to the current window width, and as a result the text below the puzzle scrolls off the bottom, then a vertical scrollbar appears and eats into the width you just maximised to. Gah. [originally from svn r9822]
* Small refactor to relative_mouse_coords: now the functionality whichSimon Tatham2013-04-07
| | | | | | | returns an element's absolute position on the web page is split out into a subfunction that can be called directly. [originally from svn r9819]
* Regretfully remove my trickery with a hidden <option> element insideSimon Tatham2013-04-05
| | | | | | | | | | | | | | | | | the game-type <select>, since IE turns out to ignore display:none on options. Oh well. Instead I now do a more transparent thing: when custom game params are in use, there's a "Custom" option selected in the dropdown, and a separate 'Re-customise' option which brings the config box back up. When an ordinary preset is selected, the Custom option is missing, and there's just a 'Customise'. In the process I've tinkered a bit to arrange that the custom 'preset' is always represented by a negative number rather than one past the last real preset; that seems more consistent overall. [originally from svn r9811]
* Rewrite the JS keyboard handling to cope with IE and Chrome.Simon Tatham2013-04-05
| | | | | | | | | | Unlike Firefox, IE and Chrome don't generate keypress events at all if you suppress the default handling of keydowns. Therefore, we have to figure out everything from the keydown event, because if we unsuppress the default handling of any keydowns then we'll get annoyances like ^R going back to meaning reload-page rather than redo-move. [originally from svn r9810]
* Stop accidentally subtracting onscreen_canvas.offset{Left,Top} fromSimon Tatham2013-04-05
| | | | | | | | the return value of relative_mouse_coords! I only got away with that error because the canvas was at offset zero compared to its immediate parent element. [originally from svn r9808]
* IE doesn't default to giving focus to the puzzle canvas on a mouseSimon Tatham2013-04-05
| | | | | | | click, so manually implement that behaviour. (Without it, it's quite hard to focus the canvas at all in IE.) [originally from svn r9806]
* Remove trailing commas at the ends of initialiser lists. IE 8 and 9Simon Tatham2013-04-05
| | | | | | | | didn't like them, which doesn't matter as such since they won't run these JS puzzles anyway (no TypedArray support) but it hints that other JS implementations might be picky about this too. [originally from svn r9804]
* Clarify header comments in the Emscripten frontend's source files toSimon Tatham2013-04-05
| | | | | | | | | | mention that the HTML pages generated by html/jspage.pl are also an integral part of this front end. (The NestedVM frontend is more self-contained, needing only an appropriate <applet> tag, but this one expects quite a few components to exist on the page and have the right ids.) [originally from svn r9803]
* Try to give a more friendly message if anything goes wrong duringSimon Tatham2013-04-03
| | | | | | | | | | puzzle startup. The puzzle web pages now enclose the whole puzzle (buttons, canvas, permalinks) in a div set to display:none, and instead display an apologetic message saying 'sorry, it didn't work'; then, if we get through the whole init function without crashing, we show the puzzle and hide the apology. [originally from svn r9802]
* Apply a bodge to arrange that if the user selects Custom from the gameSimon Tatham2013-03-31
| | | | | | | | | | | | type dropdown, we still get an 'onchange' event if they select it a second time. Normally this wouldn't happen, because onchange means what it says and we only get it if a _different_ element is selected. My solution is to create two list items called Custom, set one of them as display:none to stop it showing up when the list is dropped down, and to select it after the configuration box closes. [originally from svn r9788]
* New front end! To complement the webification of my puzzles via JavaSimon Tatham2013-03-30
applets, here's an alternative webification in Javascript, using Emscripten in asm.js mode (so that as browsers incorporate asm.js optimisation, the game generation should run really fast). [originally from svn r9781]