aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--emcc.c23
-rw-r--r--emcclib.js9
-rw-r--r--emccpre.js21
3 files changed, 37 insertions, 16 deletions
diff --git a/emcc.c b/emcc.c
index 31aedbd..25f5282 100644
--- a/emcc.c
+++ b/emcc.c
@@ -99,6 +99,8 @@ extern void js_dialog_launch(void);
extern void js_dialog_cleanup(void);
extern void js_focus_canvas(void);
+extern bool js_savefile_read(void *buf, int len);
+
/*
* These functions are called from JavaScript, so their prototypes
* need to be kept in sync with emccpre.js.
@@ -112,7 +114,7 @@ void timer_callback(double tplus);
void command(int n);
char *get_save_file(void);
void free_save_file(char *buffer);
-void load_game(const char *buffer, int len);
+void load_game(void);
void dlg_return_sval(int index, const char *val);
void dlg_return_ival(int index, int val);
void resize_puzzle(int w, int h);
@@ -904,23 +906,18 @@ struct savefile_read_ctx {
static bool 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;
+ return js_savefile_read(buf, len);
}
-void load_game(const char *buffer, int len)
+void load_game()
{
- struct savefile_read_ctx ctx;
const char *err;
- ctx.buffer = buffer;
- ctx.len_remaining = len;
- err = midend_deserialise(me, savefile_read, &ctx);
+ /*
+ * savefile_read_callback in JavaScript was set up by our caller
+ * as a closure that knows what file we're loading.
+ */
+ err = midend_deserialise(me, savefile_read, NULL);
if (err) {
js_error_box(err);
diff --git a/emcclib.js b/emcclib.js
index 07cbf3b..80d17b9 100644
--- a/emcclib.js
+++ b/emcclib.js
@@ -783,5 +783,14 @@ mergeInto(LibraryManager.library, {
*/
js_focus_canvas: function() {
onscreen_canvas.focus();
+ },
+
+ /*
+ * bool js_savefile_read(void *buf, int len);
+ *
+ * Read len bytes from the save file that we're currently loading.
+ */
+ js_savefile_read: function(buf, len) {
+ return savefile_read_callback(buf, len);
}
});
diff --git a/emccpre.js b/emccpre.js
index 2637bcb..837f815 100644
--- a/emccpre.js
+++ b/emccpre.js
@@ -135,6 +135,12 @@ var dlg_return_funcs = null;
// pass back the final value in each dialog control.
var dlg_return_sval, dlg_return_ival;
+// Callback for reading from a savefile. This will be filled in with
+// a suitable closure by the JS loading code and called by
+// js_savefile_read(). This assumes that only one file can be in the
+// process of loading at a time.
+var savefile_read_callback;
+
// The <ul> object implementing the game-type drop-down, and a list of
// the sub-lists inside it. Used by js_add_preset().
var gametypelist = document.getElementById("gametype");
@@ -423,7 +429,7 @@ function initPuzzle() {
// 'number' is used for C pointers
var get_save_file = Module.cwrap('get_save_file', 'number', []);
var free_save_file = Module.cwrap('free_save_file', 'void', ['number']);
- var load_game = Module.cwrap('load_game', 'void', ['array', 'number']);
+ var load_game = Module.cwrap('load_game', 'void', []);
if (save_button) save_button.onclick = function(event) {
if (dlg_dimmer === null) {
@@ -457,8 +463,17 @@ function initPuzzle() {
var file = input.files.item(0);
var reader = new FileReader();
reader.addEventListener("loadend", function() {
- var array = new Uint8Array(reader.result);
- load_game(array, array.length);
+ var pos = 0;
+ savefile_read_callback = function(buf, len) {
+ if (pos + len > reader.result.byteLength)
+ return false;
+ writeArrayToMemory(
+ new Int8Array(reader.result, pos, len), buf);
+ pos += len;
+ return true;
+ }
+ load_game();
+ savefile_read_callback = null;
});
reader.readAsArrayBuffer(file);
}