size_t pos;
};
-static void savefile_write(void *wctx, void *buf, int len)
+static void savefile_write(void *vctx, void *buf, int len)
{
- struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)wctx;
+ struct savefile_write_ctx *ctx = (struct savefile_write_ctx *)vctx;
if (ctx->buffer)
memcpy(ctx->buffer + ctx->pos, buf, len);
ctx->pos += len;
sfree(buffer);
}
+struct savefile_read_ctx {
+ const char *buffer;
+ int len_remaining;
+};
+
+static int savefile_read(void *vctx, void *buf, int len)
+{
+ struct savefile_read_ctx *ctx = (struct savefile_read_ctx *)vctx;
+ if (ctx->len_remaining < len)
+ return FALSE;
+ memcpy(buf, ctx->buffer, len);
+ ctx->len_remaining -= len;
+ ctx->buffer += len;
+ return TRUE;
+}
+
+void load_game(const char *buffer, int len)
+{
+ struct savefile_read_ctx ctx;
+ const char *err;
+
+ ctx.buffer = buffer;
+ ctx.len_remaining = len;
+ err = midend_deserialise(me, savefile_read, &ctx);
+
+ if (err) {
+ js_error_box(err);
+ } else {
+ select_appropriate_preset();
+ resize();
+ midend_redraw(me);
+ }
+}
+
/* ----------------------------------------------------------------------
* 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()
// 'number' is used for C pointers
get_save_file = Module.cwrap('get_save_file', 'number', []);
free_save_file = Module.cwrap('free_save_file', 'void', ['number']);
+ load_game = Module.cwrap('load_game', 'void', ['string', 'number']);
document.getElementById("save").onclick = function(event) {
if (dlg_dimmer === null) {
}
};
+ document.getElementById("load").onclick = function(event) {
+ if (dlg_dimmer === null) {
+ dialog_init("Upload saved-game file");
+ var input = document.createElement("input");
+ input.type = "file";
+ input.multiple = false;
+ dlg_form.appendChild(input);
+ dlg_form.appendChild(document.createElement("br"));
+ dialog_launch(function(event) {
+ if (input.files.length == 1) {
+ var file = input.files.item(0);
+ var reader = new FileReader();
+ reader.addEventListener("loadend", function() {
+ var string = reader.result;
+ load_game(string, string.length);
+ });
+ reader.readAsBinaryString(file);
+ }
+ dialog_cleanup();
+ }, function(event) {
+ dialog_cleanup();
+ });
+ }
+ };
+
gametypelist = document.getElementById("gametype");
gametypesubmenus.push(gametypelist);
'_timer_callback',
// Callback from button presses in the UI outside the canvas
'_command',
- // Game-saving functions
+ // Game-saving and game-loading functions
'_get_save_file',
'_free_save_file',
+ '_load_game',
// Callbacks to return values from dialog boxes
'_dlg_return_sval',
'_dlg_return_ival',
><li id="specific">Enter game ID</li
><li id="random">Enter random seed</li
><li id="save">Download save file</li
+><li id="load">Upload save file</li
></ul></li
><li>Type...<ul id="gametype"></ul></li
><li class="separator"></li