diff --git a/CMakeLists.txt b/CMakeLists.txt
index a4fdcff3a8..78b81c6238 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -337,7 +337,8 @@ if(EMSCRIPTEN)
add_definitions(-s DISABLE_EXCEPTION_CATCHING=0)
# Export functions to Javascript.
- target_link_libraries(WASM::WASM INTERFACE "-s EXPORTED_FUNCTIONS='[\"_main\",\"_em_openttd_add_server\"]' -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")
+ target_link_libraries(WASM::WASM INTERFACE "-s EXPORTED_FUNCTIONS='[\"_main\",\"_em_openttd_add_server\",\"_em_openttd_cloud_save_from_js\"]'")
+ target_link_libraries(WASM::WASM INTERFACE "-s EXPORTED_RUNTIME_METHODS='[\"cwrap\",\"ccall\"]'")
# Preload all the files we generate during build.
# As we do not compile with FreeType / FontConfig, we also have no way to
diff --git a/os/emscripten/shell.html b/os/emscripten/shell.html
index c52c4c9c78..f393969306 100644
--- a/os/emscripten/shell.html
+++ b/os/emscripten/shell.html
@@ -132,6 +132,7 @@
+
@@ -269,6 +270,7 @@
};
document.getElementById("textinput").style.display = "none"; // It's not hiding with CSS
+ //document.getElementById("loadfile").style.display = "none";
document.getElementById("canvas").focus();
window.onerror = function() {
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 5399062575..557700a9e1 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -1177,6 +1177,7 @@ void ProcessCloudSaveFromVideoThread()
elem.click();
document.body.removeChild(elem);
}, data.get(), size, lastPart );
+ status = 1;
}
#endif
if (_settings_client.gui.save_to_network == 2) {
@@ -1196,9 +1197,47 @@ void ProcessCloudSaveFromVideoThread()
_file_to_saveload.SetTitle("Network Save");
_switch_mode = SM_LOAD_GAME;
}
+#ifdef __EMSCRIPTEN__
+ EM_ASM( {
+ document.getElementById("loadfile").accept = ".sav";
+ document.getElementById("loadfile").addEventListener("change", function () {
+ if (this.files.length <= 0) {
+ return;
+ }
+ const reader = new FileReader();
+ reader.onload = function(e) {
+ const data = new Uint8Array(e.target.result);
+ const buf = Module._malloc(data.length);
+ Module.HEAPU8.set(data, buf);
+ Module.ccall("em_openttd_cloud_save_from_js", "number", ["number", "number"], [buf, data.length]);
+ Module._free(buf);
+ };
+ reader.readAsArrayBuffer(this.files[0]);
+ }, { capture: false, once: true });
+ document.getElementById("loadfile").click();
+ } );
+#endif
}
}
+#ifdef __EMSCRIPTEN__
+extern "C" void CDECL em_openttd_cloud_save_from_js(byte *buf, int size)
+{
+ static const char *NETWORK_SAVE_FILENAME = "network-save.sav";
+ std::string savePath = FiosMakeSavegameName(NETWORK_SAVE_FILENAME);
+ FILE *ff = fopen(savePath.c_str(), "wb");
+ if (!ff) {
+ return;
+ }
+ fwrite(buf, 1, size, ff);
+ fclose(ff);
+ _file_to_saveload.SetMode(FIOS_TYPE_FILE);
+ _file_to_saveload.SetName(savePath.c_str());
+ _file_to_saveload.SetTitle("Network Save");
+ _switch_mode = SM_LOAD_GAME;
+}
+#endif
+
/**
* Check the validity of some of the caches.
* Especially in the sense of desyncs between