aboutsummaryrefslogtreecommitdiff
path: root/emcc.c
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2017-09-05 20:10:16 +0100
committerSimon Tatham <anakin@pobox.com>2017-09-05 20:56:55 +0100
commit1bf591a5735068d1853be13c5a4255962835d5fe (patch)
tree9b7ee6b9396ccc38ef70ca6ba377e5b25fd0df66 /emcc.c
parentb31ea221673a8f49a383a4a119d6edaabd39642d (diff)
downloadpuzzles-1bf591a5735068d1853be13c5a4255962835d5fe.zip
puzzles-1bf591a5735068d1853be13c5a4255962835d5fe.tar.gz
puzzles-1bf591a5735068d1853be13c5a4255962835d5fe.tar.bz2
puzzles-1bf591a5735068d1853be13c5a4255962835d5fe.tar.xz
Support for saving games in Javascript puzzles.
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.
Diffstat (limited to 'emcc.c')
-rw-r--r--emcc.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/emcc.c b/emcc.c
index ca033cb..26e1ac2 100644
--- a/emcc.c
+++ b/emcc.c
@@ -757,6 +757,49 @@ void command(int n)
}
/* ----------------------------------------------------------------------
+ * Called from JS to prepare a save-game file, and free one after it's
+ * been used.
+ */
+
+struct savefile_write_ctx {
+ char *buffer;
+ size_t pos;
+};
+
+static void savefile_write(void *wctx, void *buf, int len)
+{
+ struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)wctx;
+ if (ctx->buffer)
+ memcpy(ctx->buffer + ctx->pos, buf, len);
+ ctx->pos += len;
+}
+
+char *get_save_file(void)
+{
+ struct savefile_write_ctx ctx;
+ size_t size;
+
+ /* First pass, to count up the size */
+ ctx.buffer = NULL;
+ ctx.pos = 0;
+ midend_serialise(me, savefile_write, &ctx);
+ size = ctx.pos;
+
+ /* Second pass, to actually write out the data */
+ ctx.buffer = snewn(size, char);
+ ctx.pos = 0;
+ midend_serialise(me, savefile_write, &ctx);
+ assert(ctx.pos == size);
+
+ return ctx.buffer;
+}
+
+void free_save_file(char *buffer)
+{
+ sfree(buffer);
+}
+
+/* ----------------------------------------------------------------------
* Setup function called at page load time. It's called main() because
* that's the most convenient thing in Emscripten, but it's not main()
* in the usual sense of bounding the program's entire execution.