glkote
glkote copied to clipboard
Implement graphics and sound.
Quixe side: erkyrath/quixe#3
I basically took what was there and ran with it. :) I had to expose DOM objects directly to glkote; otherwise glk_image_get_info can't work and sound won't play instantly as the spec demands. So this isn't going to work too well with RemGlk, but offhand I'm not sure how it could.
Lingering problems:
- ~~There's no deletion of images — by which I mean
<img>elements. If a story does lots of fancy image drawing, the images will just keep stacking up on top of each other, and the browser will probably start to get sad. Solving this is a tricky problem, since I'm working with discrete images rather than blitting onto a surface. I think the only options are to keep track of the position of every image and remove older images once I know they've been completely drawn over, or give up on this approach and just blit to a<canvas>.~~ - ~~Resizing doesn't clip/extend as the spec demands; it just throws away the entire contents of the graphics window. Again, this would be a massive pain to implement with a pile of
<img>s, but pretty easy with a<canvas>.~~ - ~~Floated images inside blockquotes don't quite work correctly, because the image itself isn't styled as a blockquote. But really, the blockquote style should be "hoisted" up to the entire paragraph, since it doesn't make sense to blockquote only part of a line.~~
- ~~Occasionally, it seems that an image's height and width are reported as zero, and I'm not sure why. It only happens when playing over the web, and is always fixed by refreshing. I assume something's trying to read the size of the image before it's been fully decoded by the browser, but that decoding should start while the game itself is being compiled, and should only take a moment. Yet I've had issues even when many minutes pass before the game tries to show an image.~~
- ~~Still need canvas feature detection.~~
- ~~Need sound feature detection.~~
- ~~I'm pretty sure there are some poor interactions between pausing and looping a finite number of times.~~
- Sound stuff should reeeally live in glkote, not off in quixe land, and should go through
update. - Vorbis isn't supported; there's native browser support for it (well, not in IE or Safari), but the decoding API is asynchronous, and I haven't yet figured out how to easily make the loading screen wait on it to finish.
- MOD isn't supported at all. There are some (impressive!) JavaScript libraries that can play MOD, but allegedly they are super super slow, so maybe not a good idea.
- Sound event notification isn't implemented.
But, you know, other than all that...!
Demo with sensory.gblorb here: http://stuff.veekun.com/quixe-demo/play-test.html
(I wrote that stylesheet on a whim; it's not included in the quixe PR (yet?), but one nice thing about it is that I split up the "do not touch" structural styles from the customizable ones.)
Wow, amazing work! :D
Thanks!
As I said, I am snowed under by the task(s) of shipping Hadean Lands. I will get back to this.
There will probably have to be additional engineering. For a start, I want to switch from Prototype to jQuery; there's a branch with this started but it's not up to date.
I think it's cleanest to require <canvas> for image windows.
I want to think more about how images are provided. I want to support the scenario where the images are already decoded and available at known URLs. That will both speed up processing and solve the RemGlk problem. Decoding from the blorb at runtime should remain possible, too, of course.
Yes, Prototype is pretty much dead now.
Did you say "<canvas>" and it got eaten?
Yes, that. :)
Hmm. <canvas> only works in IE 9+. Could drop support for older IE, have graphics silently fail to work in older IE, or have gestalt inspect the DOM for feature support (yikes).
I think IE 9 was the first to have a JIT JS engine; it wouldn't be unreasonable not to try running a VM on top older IEs. :)
IE8 is down to 0.41% at iplayif.com, so I say it would be fine to drop it. IE9 is at 1.25% (above IE10 actually.)
My position with Parchment has been not to preemptively ban a browser, but only when a useful feature forces me to.
That said, you probably still should test for the features, so that you can pass the information back to the VM, or have the IO system pop up a message. Don't make the glk opcode test the browser when it's called, test first and pass the information ahead when the VM starts. If you assume it's supported and it's not then you'll just get uncaught errors.
Hmm. Would having glk call a function on GiLoad be appropriate? I can't find many places quixe and glkote directly communicate outside of VM calls.
Glk.init() passes the options to GlkOte.init(). GlkOte could modify them, and then Glk could keep a reference to the options to use for glk_gestalt_ext().
Aha, I couldn't find Glk.init being called because it was on all_options.io. Cool, will take a crack at this :)
Demo updated, quixe rebuilt. This is potentially ready to go.
Turns out feature detection via init() won't work; quixe calls Glk.init() (which just does some quixe integration stuff, then calls GlkOte.init()), but the glkote documentation and examples all suggest calling GlkOte.init() directly. So instead I turned the unused val2 of the init event into a handwavey "extra" dict and stuffed feature detection in there. Canvas and audio are both feature detected now. Unfortunately old IE won't get inline images even though it could support them; gestalt isn't specific enough.
I moved AudioChannel out of quixe and into glkote, where it belongs. glkapi.js now sends audio commands as updates, in an almost-JSON-representable form, and knows as little as possible about the audio itself. (The downside is that there's no way to communicate to the VM that playing something failed.)
Still not implemented, but I think it's probably okay to go without for now:
- Sound notification. It doesn't look particularly difficult, but I'd like to do it with a game that actually makes use of it, if you have any suggestions?
- Vorbis support. The native audio decoding API is asynchronous, and I think juggling an arbitrary number of async operations will be a lot easier after a port to jQuery. (Incidentally I do have a branch that ports quixe to jQuery (based atop the existing glkote branch), and it actually runs a game!)
- MOD support.
This all Works On My Machine™, and should degrade gracefully for ancient browsers. Only potential compat issue that comes to mind is that there could be some old Chrome version that was still hammering out the Web Audio API, but those are pretty rare in the wild.
Sound notification. It doesn't look particularly difficult, but I'd like to do it with a game that actually makes use of it, if you have any suggestions?
@eevee Delphina's House has sound puzzles that are implemented in two different ways--either sound notifications or timers, depending on which sound option you choose. "Sound enabled" mode uses sound notifications.