Open curiousdannii opened 6 years ago
Filtering out the game stream when autosaving is easy enough. But now I've run into the next problem: Glk won't restore the state because the game stream already exists. I'm wondering if I could make a fake stream instead, one that doesn't get inserted into gli_streamlist.
After making a fake stream, and copying some code from iosstart.m, I have autosaves working in Glulxe :D
I still think something like glkunix_stream_open_pathname_gen could be worthwhile.
Qn: Quixe saves the random state, but iosGlulxe doesn't seem to. Am I right to think it should ideally be saved?
Edit: ah I see Glulxe is just using the libc seeded random feature, so there may not be a way to get the current state easily.
Long-term, it might be better to give the interpreters a "read the whole game file into memory and close the stream" option. (Could be a compile-time option.)
Of course who knows what "long term" means at this point, since I'm spending so little time on the interpreters any more.
Rock value isn't supposed to be meaningful; 0 is just a conventional default.
Could be. That's how Git already is. But the stream reading code is deeply embedded in the terps, and I know almost nothing about how Hugo works internally.
Continuing to make progress. I'm now getting the following error when trying to restore the Glk state:
Glulxe fatal error: Unable to re-find array argument in Glk call.
If I'm understanding correctly, I should either serialise arrays
(from glkop.c) or else get the gidispatch_set_autorestore_registry functions working. If you could tell me what the bufkey
and arrayref
params of glulxe_array_restore
mean, that would be a huge help!
Edit: Hmm, or do I comment out all calls to gli_register_arr
and gli_unregister_arr
etc, and track things only in the JS dispatch layer, and not also the C dispatch layer. That might work, I'll give it a try.
Gah, I haven't looked at this code in years...
glulxe_array_locate and glulxe_array_restore get handed to the library so that objects like glk_stream can be serialized and deserialized. glulxe_array_locate returns the VM address of a given retained array (the array that a memory stream is reading/writing to, for example.) The stream serializes this, along with the contents of the array.
glulxe_array_restore does the opposite: given a VM address (bufkey), it allocates a fresh array and hands it back (through arrayref). The memory stream stashes this as its retained array, fills it in with deserialized data, and then it's ready to continue operation.
The reason glulxe_array_restore needs the VM address info is that, when the memory stream is closed, that array will need to be shoved back into VM memory. This is handled entirely by glkop.c is normal operation. It only gets weird when you have to autosave/autorestore a live memstream.
Sorry I didn't post an update. I think I mostly figured out these functions. Particularly tricky was that the bufkey was relative to memmap (but it does make sense). I'm not getting an errors currently, but the VM does seem to be quitting one turn after an autorestore. Will dig into that more soon.
I've started working on getting autosaving to work for the Emglken VMs.
First hiccup: the games are loaded by creating a memory stream, as that's what most of the VMs want. But then when I call
Glk.save_allstate()
it wants to include the full memory stream in the JSON (stored the least efficient way possible.) Any ideas of how to exclude it?One possibility: a new function akin to
glkunix_stream_open_pathname_gen
which would set a property on the stream to exclude it fromsave_allstate
, and operating in memory rather than the file system. Though a file system version would also be useful for creating the profiling stream.Or should
save_allstate
skip any streams with a rock of0
? There's not really any way for them to be meaningfully restored, is there? Or for non retained streams with a rock of0
at least?