mirror of https://github.com/OpenTTD/OpenTTD.git
Add: [Emscripten] Support for bootstrapping
This commit is contained in:
parent
3d1c4a8589
commit
4eddec9e79
|
@ -30,24 +30,6 @@ Module.preRun.push(function() {
|
|||
|
||||
Module.addRunDependency('syncfs');
|
||||
FS.syncfs(true, function (err) {
|
||||
/* FS.mkdir() tends to fail if parent folders do not exist. */
|
||||
if (!FS.analyzePath(content_download_dir).exists) {
|
||||
FS.mkdir(content_download_dir);
|
||||
}
|
||||
if (!FS.analyzePath(content_download_dir + '/baseset').exists) {
|
||||
FS.mkdir(content_download_dir + '/baseset');
|
||||
}
|
||||
|
||||
/* Check if the OpenGFX baseset is already downloaded. */
|
||||
if (!FS.analyzePath(content_download_dir + '/baseset/opengfx-0.6.0.tar').exists) {
|
||||
window.openttd_downloaded_opengfx = true;
|
||||
FS.createPreloadedFile(content_download_dir + '/baseset', 'opengfx-0.6.0.tar', 'https://binaries.openttd.org/installer/emscripten/opengfx-0.6.0.tar', true, true);
|
||||
} else {
|
||||
/* Fake dependency increase, so the counter is stable. */
|
||||
Module.addRunDependency('opengfx');
|
||||
Module.removeRunDependency('opengfx');
|
||||
}
|
||||
|
||||
Module.removeRunDependency('syncfs');
|
||||
});
|
||||
|
||||
|
@ -74,6 +56,23 @@ Module.preRun.push(function() {
|
|||
window.openttd_syncfs(Module.onAbort);
|
||||
}
|
||||
|
||||
window.openttd_bootstrap = function(current, total) {
|
||||
Module.onBootstrap(current, total);
|
||||
}
|
||||
|
||||
window.openttd_bootstrap_failed = function() {
|
||||
Module.onBootstrapFailed();
|
||||
}
|
||||
|
||||
window.openttd_bootstrap_reload = function() {
|
||||
window.openttd_syncfs(function() {
|
||||
Module.onBootstrapReload();
|
||||
setTimeout(function() {
|
||||
location.reload();
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
window.openttd_server_list = function() {
|
||||
add_server = Module.cwrap("em_openttd_add_server", null, ["string"]);
|
||||
|
||||
|
@ -125,11 +124,3 @@ Module.preRun.push(function() {
|
|||
return ret;
|
||||
}
|
||||
});
|
||||
|
||||
Module.postRun.push(function() {
|
||||
/* Check if we downloaded OpenGFX; if so, sync the virtual FS back to the
|
||||
* IDBFS so OpenGFX is stored persistent. */
|
||||
if (window['openttd_downloaded_opengfx']) {
|
||||
FS.syncfs(false, function (err) { });
|
||||
}
|
||||
});
|
||||
|
|
|
@ -75,7 +75,6 @@
|
|||
}
|
||||
#message {
|
||||
color: #101010;
|
||||
height: 54px;
|
||||
padding: 4px 4px;
|
||||
}
|
||||
|
||||
|
@ -144,6 +143,8 @@
|
|||
})(),
|
||||
|
||||
setStatus: function(text) {
|
||||
if (document.getElementById("canvas").style.display == "none") return;
|
||||
|
||||
var m = text.match(/^([^(]+)\((\d+(\.\d+)?)\/(\d+)\)$/);
|
||||
|
||||
if (m) {
|
||||
|
@ -171,6 +172,27 @@
|
|||
document.getElementById("message").innerHTML = "Preparing game ...";
|
||||
},
|
||||
|
||||
onBootstrap: function(current, total) {
|
||||
document.getElementById("canvas").style.display = "none";
|
||||
|
||||
document.getElementById("title").innerHTML = "Missing base graphics";
|
||||
document.getElementById("message").innerHTML = "OpenTTD is downloading base graphics.<br/><br/>" + current + " / " + total + " bytes downloaded.";
|
||||
},
|
||||
|
||||
onBootstrapFailed: function(current, total) {
|
||||
document.getElementById("canvas").style.display = "none";
|
||||
|
||||
document.getElementById("title").innerHTML = "Missing base graphics";
|
||||
document.getElementById("message").innerHTML = "Failed to download base graphics.<br/>The game cannot start without base graphics.<br/><br/>Please check your Internet connection and/or the console log.<br/>Reload your browser to try again.";
|
||||
},
|
||||
|
||||
onBootstrapReload: function() {
|
||||
document.getElementById("canvas").style.display = "none";
|
||||
|
||||
document.getElementById("title").innerHTML = "Missing base graphics";
|
||||
document.getElementById("message").innerHTML = "Downloading base graphics done.<br/><br/>Your browser will reload to start the game.";
|
||||
},
|
||||
|
||||
onExit: function() {
|
||||
document.getElementById("canvas").style.display = "none";
|
||||
|
||||
|
|
|
@ -286,6 +286,76 @@ public:
|
|||
|
||||
#endif /* defined(WITH_FREETYPE) */
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
# include <emscripten.h>
|
||||
# include "network/network.h"
|
||||
# include "network/network_content.h"
|
||||
# include "openttd.h"
|
||||
# include "video/video_driver.hpp"
|
||||
|
||||
class BootstrapEmscripten : public ContentCallback {
|
||||
bool downloading{false};
|
||||
uint total_files{0};
|
||||
uint total_bytes{0};
|
||||
uint downloaded_bytes{0};
|
||||
|
||||
public:
|
||||
BootstrapEmscripten()
|
||||
{
|
||||
_network_content_client.AddCallback(this);
|
||||
_network_content_client.Connect();
|
||||
}
|
||||
|
||||
~BootstrapEmscripten()
|
||||
{
|
||||
_network_content_client.RemoveCallback(this);
|
||||
}
|
||||
|
||||
void OnConnect(bool success) override
|
||||
{
|
||||
if (!success) {
|
||||
EM_ASM({ if (window["openttd_bootstrap_failed"]) openttd_bootstrap_failed(); });
|
||||
return;
|
||||
}
|
||||
|
||||
/* Once connected, request the metadata. */
|
||||
_network_content_client.RequestContentList(CONTENT_TYPE_BASE_GRAPHICS);
|
||||
}
|
||||
|
||||
void OnReceiveContentInfo(const ContentInfo *ci) override
|
||||
{
|
||||
if (this->downloading) return;
|
||||
|
||||
/* And once the metadata is received, start downloading it. */
|
||||
_network_content_client.Select(ci->id);
|
||||
_network_content_client.DownloadSelectedContent(this->total_files, this->total_bytes);
|
||||
this->downloading = true;
|
||||
|
||||
EM_ASM({ if (window["openttd_bootstrap"]) openttd_bootstrap($0, $1); }, this->downloaded_bytes, this->total_bytes);
|
||||
}
|
||||
|
||||
void OnDownloadProgress(const ContentInfo *ci, int bytes) override
|
||||
{
|
||||
/* A negative value means we are resetting; for example, when retrying or using a fallback. */
|
||||
if (bytes < 0) {
|
||||
this->downloaded_bytes = 0;
|
||||
} else {
|
||||
this->downloaded_bytes += bytes;
|
||||
}
|
||||
|
||||
EM_ASM({ if (window["openttd_bootstrap"]) openttd_bootstrap($0, $1); }, this->downloaded_bytes, this->total_bytes);
|
||||
}
|
||||
|
||||
void OnDownloadComplete(ContentID cid) override
|
||||
{
|
||||
/* _exit_game is used to break out of the outer video driver's MainLoop. */
|
||||
_exit_game = true;
|
||||
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
#endif /* __EMSCRIPTEN__ */
|
||||
|
||||
/**
|
||||
* Handle all procedures for bootstrapping OpenTTD without a base graphics set.
|
||||
* This requires all kinds of trickery that is needed to avoid the use of
|
||||
|
@ -300,12 +370,15 @@ bool HandleBootstrap()
|
|||
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure;
|
||||
|
||||
/* If there is no network or no non-sprite font, then there is nothing we can do. Go straight to failure. */
|
||||
#if (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA)
|
||||
#if defined(__EMSCRIPTEN__) || (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA)
|
||||
if (!_network_available) goto failure;
|
||||
|
||||
/* First tell the game we're bootstrapping. */
|
||||
_game_mode = GM_BOOTSTRAP;
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
new BootstrapEmscripten();
|
||||
#else
|
||||
/* Initialise the font cache. */
|
||||
InitializeUnicodeGlyphMap();
|
||||
/* Next "force" finding a suitable non-sprite font as the local font is missing. */
|
||||
|
@ -324,6 +397,7 @@ bool HandleBootstrap()
|
|||
/* Finally ask the question. */
|
||||
new BootstrapBackground();
|
||||
new BootstrapAskForDownloadWindow();
|
||||
#endif /* __EMSCRIPTEN__ */
|
||||
|
||||
/* Process the user events. */
|
||||
VideoDriver::GetInstance()->MainLoop();
|
||||
|
|
|
@ -615,7 +615,11 @@ void VideoDriver_SDL_Base::LoopOnce()
|
|||
/* In effect, the game ends here. As emscripten_set_main_loop() caused
|
||||
* the stack to be unwound, the code after MainLoop() in
|
||||
* openttd_main() is never executed. */
|
||||
EM_ASM(if (window["openttd_exit"]) openttd_exit());
|
||||
if (_game_mode == GM_BOOTSTRAP) {
|
||||
EM_ASM(if (window["openttd_bootstrap_reload"]) openttd_bootstrap_reload());
|
||||
} else {
|
||||
EM_ASM(if (window["openttd_exit"]) openttd_exit());
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue