Update docs and example page

This commit is contained in:
Insality
2024-10-17 02:02:07 +03:00
parent 3579370287
commit dd41aab962
46 changed files with 10684 additions and 540 deletions

View File

@@ -1,3 +1,93 @@
/*
* 'archive_location_filter':
* Filter function that will run for each archive path.
*
* 'unsupported_webgl_callback':
* Function that is called if WebGL is not supported.
*
* 'engine_arguments':
* List of arguments (strings) that will be passed to the engine.
*
* 'custom_heap_size':
* Number of bytes specifying the memory heap size.
*
* 'disable_context_menu':
* Disables the right-click context menu on the canvas element if true.
*
* 'retry_time':
* Pause before retry file loading after error.
*
* 'retry_count':
* How many attempts we do when trying to download a file.
*
* 'can_not_download_file_callback':
* Function that is called if you can't download file after 'retry_count' attempts.
*
* 'exe_name':
* Executable name which used for find right binary to load
*
* 'resize_window_callback':
* Function that is called when resize/orientationchanges/focus events happened
*/
var CUSTOM_PARAMETERS = {
archive_location_filter: function( path ) {
return ("archive" + path + "");
},
engine_arguments: ["--verify-graphics-calls=false",],
custom_heap_size: 67108864,
full_screen_container: "#canvas-container",
disable_context_menu: true,
retry_time:1.0,
retry_count:10,
unsupported_webgl_callback: function() {
var e = document.getElementById("webgl-not-supported");
e.style.display = "block";
},
resize_window_callback: function() {
var is_iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
var buttonHeight = 0;
var prevInnerWidth = -1;
var prevInnerHeight = -1;
// Hack for iOS when exit from Fullscreen mode
if (is_iOS) {
window.scrollTo(0, 0);
}
var app_container = document.getElementById('app-container');
var game_canvas = document.getElementById('canvas');
var innerWidth = window.innerWidth;
var innerHeight = window.innerHeight - buttonHeight;
if (prevInnerWidth == innerWidth && prevInnerHeight == innerHeight)
{
return;
}
prevInnerWidth = innerWidth;
prevInnerHeight = innerHeight;
var width = 1920;
var height = 1080;
var targetRatio = width / height;
var actualRatio = innerWidth / innerHeight;
//Stretch
width = innerWidth;
height = innerHeight;
var dpi = 1;
dpi = window.devicePixelRatio || 1;
app_container.style.width = width + "px";
app_container.style.height = height + buttonHeight + "px";
game_canvas.width = Math.floor(width * dpi);
game_canvas.height = Math.floor(height * dpi);
}
}
// file downloader
// wraps XMLHttpRequest and adds retry support and progress updates when the
// content is gzipped (gzipped content doesn't report a computable content length
@@ -9,31 +99,36 @@ var FileLoader = {
},
// do xhr request with retries
request: function(url, method, responseType, currentAttempt) {
if (typeof method === 'undefined') throw "No method specified";
if (typeof method === 'responseType') throw "No responseType specified";
if (typeof method === 'undefined') throw TypeError("No method specified");
if (typeof method === 'responseType') throw TypeError("No responseType specified");
if (typeof currentAttempt === 'undefined') currentAttempt = 0;
var obj = {
send: function() {
var onprogress = this.onprogress;
var onload = this.onload;
var onerror = this.onerror;
var onretry = this.onretry;
var xhr = new XMLHttpRequest();
xhr._loadedSize = 0;
xhr.open(method, url, true);
xhr.responseType = responseType;
xhr.onprogress = function(e) {
if (onprogress) onprogress(xhr, e);
xhr.onprogress = function(event) {
if (onprogress) onprogress(xhr, event, xhr._loadedSize);
xhr._loadedSize = event.loaded;
};
xhr.onerror = function(e) {
xhr.onerror = function(event) {
if (currentAttempt == FileLoader.options.retryCount) {
if (onerror) onerror(xhr, e);
if (onerror) onerror(xhr, event);
return;
}
currentAttempt = currentAttempt + 1;
if (onretry) onretry(xhr, event, xhr._loadedSize, currentAttempt);
xhr._loadedSize = 0;
currentAttempt += 1;
setTimeout(obj.send.bind(obj), FileLoader.options.retryInterval);
};
xhr.onload = function(e) {
if (onload) onload(xhr, e);
xhr.onload = function(event) {
if (onload) onload(xhr, event);
};
xhr.send(null);
}
@@ -60,29 +155,21 @@ var FileLoader = {
request.send();
},
// Do HTTP GET request
// onprogress(loaded, total)
// onprogress(loadedDelta)
// onerror(error)
// onload(response)
load: function(url, responseType, estimatedSize, onprogress, onerror, onload) {
// onretry(loadedSize, currentAttempt)
load: function(url, responseType, onprogress, onerror, onload, onretry) {
var request = FileLoader.request(url, "GET", responseType);
request.onprogress = function(xhr, e) {
if (e.lengthComputable) {
onprogress(e.loaded, e.total);
return;
}
var contentLength = xhr.getResponseHeader('content-length');
var size = contentLength != undefined ? contentLength : estimatedSize;
if (size) {
onprogress(e.loaded, size);
} else {
onprogress(e.loaded, e.loaded);
}
request.onprogress = function(xhr, e, ls) {
var delta = e.loaded - ls;
onprogress(delta);
};
request.onerror = function(xhr, e) {
onerror("Error loading '" + url + "' (" + e + ")");
};
request.onload = function(xhr, e) {
if (xhr.readyState === 4) {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
var res = xhr.response;
if (responseType == "json" && typeof res === "string") {
@@ -95,113 +182,145 @@ var FileLoader = {
}
}
};
request.onretry = function(xhr, event, loadedSize, currentAttempt) {
onretry(loadedSize, currentAttempt);
}
request.send();
}
};
var EngineLoader = {
wasm_size: 2000000,
wasmjs_size: 250000,
wasm_size: 2374239,
wasmjs_size: 340441,
asmjs_size: 4000000,
wasm_instantiate_progress: 0,
stream_wasm: false,
stream_wasm: "false" === "true",
loadAndInstantiateWasmAsync: function(src, fromProgress, toProgress, callback) {
FileLoader.load(src, "arraybuffer", EngineLoader.wasm_size,
function(loaded, total) { Progress.calculateProgress(fromProgress, toProgress, loaded, total); },
updateWasmInstantiateProgress: function(totalDownloadedSize) {
EngineLoader.wasm_instantiate_progress = totalDownloadedSize * 0.1;
},
// load and instantiate .wasm file using XMLHttpRequest
loadAndInstantiateWasmAsync: function(src, imports, successCallback) {
FileLoader.load(src, "arraybuffer",
function(delta) {
ProgressUpdater.updateCurrent(delta);
},
function(error) { throw error; },
function(wasm) {
Module.instantiateWasm = function(imports, successCallback) {
var wasmInstantiate = WebAssembly.instantiate(new Uint8Array(wasm), imports).then(function(output) {
successCallback(output.instance);
}).catch(function(e) {
console.log('wasm instantiation failed! ' + e);
throw e;
});
return {}; // Compiling asynchronously, no exports.
if (wasm.byteLength != EngineLoader.wasm_size) {
throw "Invalid wasm size. Expected: " + EngineLoader.wasm_size + ", actual: " + wasm.byteLength;
}
callback();
var wasmInstantiate = WebAssembly.instantiate(new Uint8Array(wasm), imports).then(function(output) {
successCallback(output.instance);
}).catch(function(e) {
console.log('wasm instantiation failed! ' + e);
throw e;
});
},
function(loadedDelta, currentAttempt){
ProgressUpdater.updateCurrent(-loadedDelta);
});
},
setupWasmStreamAsync: async function(src, fromProgress, toProgress) {
// stream and instantiate .wasm file
streamAndInstantiateWasmAsync: async function(src, imports, successCallback) {
// https://stackoverflow.com/a/69179454
var fetchFn = fetch;
if (typeof TransformStream === "function" && ReadableStream.prototype.pipeThrough) {
async function fetchWithProgress(path) {
const response = await fetch(path);
// May be incorrect if compressed
var contentLength = response.headers.get("Content-Length");
if (!contentLength){
contentLength = EngineLoader.wasm_size;
if (response.ok) {
const ts = new TransformStream({
transform (chunk, controller) {
ProgressUpdater.updateCurrent(chunk.byteLength);
controller.enqueue(chunk);
}
});
return new Response(response.body.pipeThrough(ts), response);
} else {
return new Response(null, response);
}
const total = parseInt(contentLength, 10);
let bytesLoaded = 0;
const ts = new TransformStream({
transform (chunk, controller) {
bytesLoaded += chunk.byteLength;
Progress.calculateProgress(fromProgress, toProgress, bytesLoaded, total);
controller.enqueue(chunk)
}
});
return new Response(response.body.pipeThrough(ts), response);
}
fetchFn = fetchWithProgress;
}
Module.instantiateWasm = function(imports, successCallback) {
WebAssembly.instantiateStreaming(fetchFn(src), imports).then(function(output) {
Progress.calculateProgress(fromProgress, toProgress, 1, 1);
successCallback(output.instance);
}).catch(function(e) {
console.log('wasm streaming instantiation failed! ' + e);
throw e;
});
return {}; // Compiling asynchronously, no exports.
}
WebAssembly.instantiateStreaming(fetchFn(src), imports).then(function(output) {
ProgressUpdater.updateCurrent(EngineLoader.wasm_instantiate_progress);
successCallback(output.instance);
}).catch(function(e) {
console.log('wasm streaming instantiation failed! ' + e);
console.log('Fallback to wasm loading');
EngineLoader.loadAndInstantiateWasmAsync(src, imports, successCallback);
});
},
// instantiate the .wasm file either by streaming it or first loading and then instantiate it
// https://github.com/emscripten-core/emscripten/blob/master/tests/manual_wasm_instantiate.html#L170
// https://github.com/emscripten-core/emscripten/blob/main/test/manual_wasm_instantiate.html
loadWasmAsync: function(exeName) {
if (EngineLoader.stream_wasm && (typeof WebAssembly.instantiateStreaming === "function")) {
EngineLoader.setupWasmStreamAsync(exeName + ".wasm", 10, 50);
EngineLoader.loadAndRunScriptAsync(exeName + '_wasm.js', EngineLoader.wasmjs_size, 0, 10);
}
else {
EngineLoader.loadAndInstantiateWasmAsync(exeName + ".wasm", 0, 40, function() {
EngineLoader.loadAndRunScriptAsync(exeName + '_wasm.js', EngineLoader.wasmjs_size, 40, 50);
});
}
Module.instantiateWasm = function(imports, successCallback) {
if (EngineLoader.stream_wasm && (typeof WebAssembly.instantiateStreaming === "function")) {
EngineLoader.streamAndInstantiateWasmAsync(exeName + ".wasm", imports, successCallback);
}
else {
EngineLoader.loadAndInstantiateWasmAsync(exeName + ".wasm", imports, successCallback);
}
return {}; // Compiling asynchronously, no exports.
};
EngineLoader.loadAndRunScriptAsync(exeName + '_wasm.js');
},
loadAsmJsAsync: function(exeName) {
EngineLoader.loadAndRunScriptAsync(exeName + '_asmjs.js', EngineLoader.asmjs_size, 0, 50);
EngineLoader.loadAndRunScriptAsync(exeName + '_asmjs.js');
},
// load and start engine script (asm.js or wasm.js)
loadAndRunScriptAsync: function(src, estimatedSize, fromProgress, toProgress) {
FileLoader.load(src, "text", estimatedSize,
function(loaded, total) { Progress.calculateProgress(fromProgress, toProgress, loaded, total); },
loadAndRunScriptAsync: function(src) {
FileLoader.load(src, "text",
function(delta) {
ProgressUpdater.updateCurrent(delta);
},
function(error) { throw error; },
function(response) {
var tag = document.createElement("script");
tag.text = response;
document.body.appendChild(tag);
},
function(loadedDelta, currentAttempt){
ProgressUpdater.updateCurrent(-loadedDelta);
});
},
// load engine (asm.js or wasm.js + wasm)
// left as entrypoint for backward capability
// start loading archive_files.json
// after receiving it - start loading engine and data concurrently
load: function(appCanvasId, exeName) {
Progress.addProgress(Module.setupCanvas(appCanvasId));
if (Module['isWASMSupported']) {
EngineLoader.loadWasmAsync(exeName);
} else {
EngineLoader.loadAsmJsAsync(exeName);
ProgressView.addProgress(Module.setupCanvas(appCanvasId));
CUSTOM_PARAMETERS['exe_name'] = exeName;
FileLoader.options.retryCount = CUSTOM_PARAMETERS["retry_count"];
FileLoader.options.retryInterval = CUSTOM_PARAMETERS["retry_time"] * 1000;
if (typeof CUSTOM_PARAMETERS["can_not_download_file_callback"] === "function") {
GameArchiveLoader.addFileDownloadErrorListener(CUSTOM_PARAMETERS["can_not_download_file_callback"]);
}
// Load and assemble archive
GameArchiveLoader.addFileLoadedListener(Module.onArchiveFileLoaded);
GameArchiveLoader.addArchiveLoadedListener(Module.onArchiveLoaded);
GameArchiveLoader.setFileLocationFilter(CUSTOM_PARAMETERS["archive_location_filter"]);
GameArchiveLoader.loadArchiveDescription('/archive_files.json');
// move resize callback setup here to make possible to override callback
// from outside of dmloader.js
if (typeof CUSTOM_PARAMETERS["resize_window_callback"] === "function") {
var callback = CUSTOM_PARAMETERS["resize_window_callback"]
callback();
window.addEventListener('resize', callback, false);
window.addEventListener('orientationchange', callback, false);
window.addEventListener('focus', callback, false);
}
}
}
@@ -232,9 +351,6 @@ var GameArchiveLoader = {
_onArchiveLoadedListeners:[], // signature: void
_onFileDownloadErrorListeners: [], // signature: name
_currentDownloadBytes: 0,
_totalDownloadBytes: 0,
_archiveLocationFilter: function(path) { return "split" + path; },
cleanUp: function() {
@@ -244,13 +360,10 @@ var GameArchiveLoader = {
this._onGameArchiveLoaderCompletedListeners = [];
this._onAllTargetsBuiltListeners = [];
this._onFileDownloadErrorListeners = [];
this._currentDownloadBytes = 0;
this._totalDownloadBytes = 0;
},
addListener: function(list, callback) {
if (typeof callback !== 'function') throw "Invalid callback registration";
if (typeof callback !== 'function') throw TypeError("Invalid callback registration");
list.push(callback);
},
notifyListeners: function(list, data) {
@@ -292,22 +405,31 @@ var GameArchiveLoader = {
FileLoader.load(
this._archiveLocationFilter(descriptionUrl),
"json",
undefined,
function (loaded, total) { },
function (delta) { },
function (error) { GameArchiveLoader.notifyFileDownloadError(descriptionUrl); },
function (json) { GameArchiveLoader.onReceiveDescription(json); });
function (json) { GameArchiveLoader.onReceiveDescription(json); },
function (loadedDelta, currentAttempt) { });
},
onReceiveDescription: function(json) {
var totalSize = json.total_size;
var exeName = CUSTOM_PARAMETERS['exe_name'];
this._files = json.content;
this._totalDownloadBytes = 0;
this._currentDownloadBytes = 0;
// calculate total download size of all files
for(var i=0; i<this._files.length; ++i) {
this._totalDownloadBytes += this._files[i].size;
var isWASMSupported = Module['isWASMSupported'];
if (isWASMSupported) {
EngineLoader.loadWasmAsync(exeName);
totalSize += EngineLoader.wasm_size + EngineLoader.wasmjs_size;
} else {
EngineLoader.loadAsmJsAsync(exeName);
totalSize += EngineLoader.asmjs_size;
}
this.downloadContent();
ProgressUpdater.resetCurrent();
if (isWASMSupported) {
EngineLoader.updateWasmInstantiateProgress(totalSize);
}
ProgressUpdater.setupTotal(totalSize + EngineLoader.wasm_instantiate_progress);
},
downloadContent: function() {
@@ -327,30 +449,25 @@ var GameArchiveLoader = {
}
},
notifyDownloadProgress: function() {
Progress.calculateProgress(50, 100, this._currentDownloadBytes, this._totalDownloadBytes);
notifyDownloadProgress: function(delta) {
ProgressUpdater.updateCurrent(delta);
},
downloadPiece: function(file, index) {
if (index < file.lastRequestedPiece) {
throw "Request out of order";
throw RangeError("Request out of order: " + file.name + ", index: " + index + ", last requested piece: " + file.lastRequestedPiece);
}
var piece = file.pieces[index];
file.lastRequestedPiece = index;
file.totalLoadedPieces = 0;
var total = 0;
var downloaded = 0;
var url = this._archiveLocationFilter('/' + piece.name);
FileLoader.load(
url, "arraybuffer", undefined,
function (loaded, total) {
var delta = loaded - downloaded;
downloaded = loaded;
GameArchiveLoader._currentDownloadBytes += delta;
GameArchiveLoader.notifyDownloadProgress();
url, "arraybuffer",
function (delta) {
GameArchiveLoader.notifyDownloadProgress(delta);
},
function (error) {
GameArchiveLoader.notifyFileDownloadError(error);
@@ -361,8 +478,10 @@ var GameArchiveLoader = {
total = piece.dataLength;
downloaded = piece.dataLength;
GameArchiveLoader.onPieceLoaded(file, piece);
GameArchiveLoader.notifyDownloadProgress();
piece.data = undefined;
},
function(loadedDelta, currentAttempt){
ProgressUpdater.updateCurrent(-loadedDelta);
});
},
@@ -373,10 +492,10 @@ var GameArchiveLoader = {
var start = piece.offset;
var end = start + piece.data.length;
if (0 > start) {
throw "Buffer underflow";
throw RangeError("Buffer underflow. Start: " + start);
}
if (end > file.data.length) {
throw "Buffer overflow";
throw RangeError("Buffer overflow. End : " + end + ", data length: " + file.data.length);
}
file.data.set(piece.data, piece.offset);
}
@@ -407,12 +526,11 @@ var GameArchiveLoader = {
actualSize += file.pieces[i].dataLength;
}
if (actualSize != file.size) {
throw "Unexpected data size";
throw "Unexpected data size: " + file.name + ", expected size: " + file.size + ", actual size: " + actualSize;
}
// verify the pieces
if (file.pieces.length > 1) {
var output = file.data;
var pieces = file.pieces;
for (i=0; i<pieces.length; ++i) {
var item = pieces[i];
@@ -422,13 +540,13 @@ var GameArchiveLoader = {
if (0 < i) {
var previous = pieces[i - 1];
if (previous.offset + previous.dataLength > start) {
throw "Segment underflow";
throw RangeError("Segment underflow in file: " + file.name + ", offset: " + (previous.offset + previous.dataLength) + " , start: " + start);
}
}
if (pieces.length - 2 > i) {
var next = pieces[i + 1];
if (end > next.offset) {
throw "Segment overflow";
throw RangeError("Segment overflow in file: " + file.name + ", offset: " + next.offset + ", end: " + end);
}
}
}
@@ -456,14 +574,42 @@ var GameArchiveLoader = {
/* Default splash and progress visualisation */
/* ********************************************************************* */
var Progress = {
var ProgressView = {
progress_id: "defold-progress",
bar_id: "defold-progress-bar",
addProgress : function (canvas) {
/* Insert default progress bar below canvas */
canvas.insertAdjacentHTML('afterend', '<div id="' + ProgressView.progress_id + '" class="canvas-app-progress"><div id="' + ProgressView.bar_id + '" class="canvas-app-progress-bar" style="transform: scaleX(0.0);"></div></div>');
ProgressView.bar = document.getElementById(ProgressView.bar_id);
ProgressView.progress = document.getElementById(ProgressView.progress_id);
},
updateProgress: function(percentage) {
if (ProgressView.bar) {
ProgressView.bar.style.transform = "scaleX(" + Math.min(percentage, 100) / 100 + ")";
}
},
removeProgress: function () {
if (ProgressView.progress.parentElement !== null) {
ProgressView.progress.parentElement.removeChild(ProgressView.progress);
// Remove any background/splash image that was set in runApp().
// Workaround for Safari bug DEF-3061.
Module.canvas.style.background = "";
}
}
};
var ProgressUpdater = {
current: 0,
total: 1,
listeners: [],
addListener: function(callback) {
if (typeof callback !== 'function') throw "Invalid callback registration";
if (typeof callback !== 'function') throw TypeError("Invalid callback registration");
this.listeners.push(callback);
},
@@ -473,32 +619,64 @@ var Progress = {
}
},
setupTotal: function (total) {
this.total = total;
},
setCurrent: function (current) {
this.current = current;
var percentage = this.calculateProgress();
ProgressView.updateProgress(percentage);
this.notifyListeners(percentage);
},
updateCurrent: function (diff) {
this.current += diff;
var percentage = this.calculateProgress();
ProgressView.updateProgress(percentage);
this.notifyListeners(percentage);
},
resetCurrent: function () {
this.current = 0;
},
complete: function () {
this.setCurrent(this.total);
},
calculateProgress: function () {
return this.current / this.total * 100;
}
};
/* DEPRECATED!
* Use ProgressUpdater and ProgressView instead.
* Left for backward compatability.
*/
var Progress = {
addListener: function(callback) {
ProgressUpdater.addListener(callback);
},
notifyListeners: function(percentage) {
// no-op
},
addProgress : function (canvas) {
/* Insert default progress bar below canvas */
canvas.insertAdjacentHTML('afterend', '<div id="' + Progress.progress_id + '" class="canvas-app-progress"><div id="' + Progress.bar_id + '" class="canvas-app-progress-bar" style="width: 0%;"></div></div>');
Progress.bar = document.getElementById(Progress.bar_id);
Progress.progress = document.getElementById(Progress.progress_id);
ProgressView.addProgress(canvas);
},
updateProgress: function(percentage) {
if (Progress.bar) {
Progress.bar.style.width = percentage + "%";
}
Progress.notifyListeners(percentage);
// no-op
},
calculateProgress: function (from, to, current, total) {
this.updateProgress(from + (current / total) * (to - from));
// no-op
},
removeProgress: function () {
if (Progress.progress.parentElement !== null) {
Progress.progress.parentElement.removeChild(Progress.progress);
// Remove any background/splash image that was set in runApp().
// Workaround for Safari bug DEF-3061.
Module.canvas.style.background = "";
}
ProgressView.removeProgress();
}
};
@@ -512,7 +690,7 @@ var Module = {
_filesToPreload: [],
_archiveLoaded: false,
_preLoadDone: false,
_waitingForArchive: false,
_isEngineLoaded: false,
// Persistent storage
persistentStorage: true,
@@ -550,7 +728,6 @@ var Module = {
var error = errObj || (typeof window.event != "undefined" ? window.event.error : "" ) || err || "Undefined Error";
var message = "";
var stack = "";
var backtrace = "";
if (typeof error == "object" && typeof error.stack != "undefined" && typeof error.message != "undefined") {
stack = String(error.stack);
@@ -603,61 +780,14 @@ var Module = {
/**
* Module.runApp - Starts the application given a canvas element id
*
* 'extra_params' is an optional object that can have the following fields:
*
* 'archive_location_filter':
* Filter function that will run for each archive path.
*
* 'unsupported_webgl_callback':
* Function that is called if WebGL is not supported.
*
* 'engine_arguments':
* List of arguments (strings) that will be passed to the engine.
*
* 'persistent_storage':
* Boolean toggling the usage of persistent storage.
*
* 'custom_heap_size':
* Number of bytes specifying the memory heap size.
*
* 'disable_context_menu':
* Disables the right-click context menu on the canvas element if true.
*
* 'retry_time':
* Pause before retry file loading after error.
*
* 'retry_count':
* How many attempts we do when trying to download a file.
*
* 'can_not_download_file_callback':
* Function that is called if you can't download file after 'retry_count' attempts.
**/
runApp: function(appCanvasId, extra_params) {
runApp: function(appCanvasId, _) {
Module._isEngineLoaded = true;
Module.setupCanvas(appCanvasId);
var params = {
archive_location_filter: function(path) { return 'split' + path; },
unsupported_webgl_callback: undefined,
engine_arguments: [],
persistent_storage: true,
custom_heap_size: undefined,
disable_context_menu: true,
retry_time: 1,
retry_count: 10,
can_not_download_file_callback: undefined,
};
Module.arguments = CUSTOM_PARAMETERS["engine_arguments"];
for (var k in extra_params) {
if (extra_params.hasOwnProperty(k)) {
params[k] = extra_params[k];
}
}
Module.arguments = params["engine_arguments"];
Module.persistentStorage = params["persistent_storage"];
var fullScreenContainer = params["full_screen_container"];
var fullScreenContainer = CUSTOM_PARAMETERS["full_screen_container"];
if (typeof fullScreenContainer === "string") {
fullScreenContainer = document.querySelector(fullScreenContainer);
}
@@ -667,31 +797,22 @@ var Module = {
Module.canvas.focus();
// Add context menu hide-handler if requested
if (params["disable_context_menu"])
if (CUSTOM_PARAMETERS["disable_context_menu"])
{
Module.canvas.oncontextmenu = function(e) {
e.preventDefault();
};
}
FileLoader.options.retryCount = params["retry_count"];
FileLoader.options.retryInterval = params["retry_time"] * 1000;
if (typeof params["can_not_download_file_callback"] === "function") {
GameArchiveLoader.addFileDownloadErrorListener(params["can_not_download_file_callback"]);
}
// Load and assemble archive
GameArchiveLoader.addFileLoadedListener(Module.onArchiveFileLoaded);
GameArchiveLoader.addArchiveLoadedListener(Module.onArchiveLoaded);
GameArchiveLoader.setFileLocationFilter(params["archive_location_filter"]);
GameArchiveLoader.loadArchiveDescription('/archive_files.json');
Module._preloadAndCallMain();
} else {
Progress.updateProgress(100, "Unable to start game, WebGL not supported");
// "Unable to start game, WebGL not supported"
ProgressUpdater.complete();
Module.setStatus = function(text) {
if (text) Module.printErr('[missing WebGL] ' + text);
};
if (typeof params["unsupported_webgl_callback"] === "function") {
params["unsupported_webgl_callback"]();
if (typeof CUSTOM_PARAMETERS["unsupported_webgl_callback"] === "function") {
CUSTOM_PARAMETERS["unsupported_webgl_callback"]();
}
}
},
@@ -703,11 +824,7 @@ var Module = {
onArchiveLoaded: function() {
GameArchiveLoader.cleanUp();
Module._archiveLoaded = true;
Progress.updateProgress(100, "Starting...");
if (Module._waitingForArchive) {
Module._preloadAndCallMain();
}
Module._preloadAndCallMain();
},
toggleFullscreen: function(element) {
@@ -720,7 +837,6 @@ var Module = {
preSync: function(done) {
if (Module.persistentStorage != true) {
Module._syncInitial = true;
done();
return;
}
@@ -820,26 +936,33 @@ var Module = {
postRun: [function() {
if(Module._archiveLoaded) {
Progress.removeProgress();
ProgressView.removeProgress();
}
}],
_preloadAndCallMain: function() {
// If the archive isn't loaded,
// we will have to wait with calling main.
if (!Module._archiveLoaded) {
Module._waitingForArchive = true;
} else {
Module.preloadAll();
Progress.removeProgress();
if (Module.callMain === undefined) {
Module.noInitialRun = false;
} else {
Module.callMain(Module.arguments);
if (Module._syncInitial || Module.persistentStorage != true) {
// If the archive isn't loaded,
// we will have to wait with calling main.
if (Module._archiveLoaded) {
Module.preloadAll();
if (Module._isEngineLoaded) {
// "Starting...."
ProgressUpdater.complete();
Module._callMain();
}
}
}
},
_callMain: function() {
ProgressView.removeProgress();
if (Module.callMain === undefined) {
Module.noInitialRun = false;
} else {
Module.callMain(Module.arguments);
}
},
// Wrap IDBFS syncfs call with logic to avoid multiple syncs
// running at the same time.
_startSyncFS: function() {
@@ -864,6 +987,26 @@ var Module = {
},
};
// common engine setup
Module['persistentStorage'] = (typeof window !== 'undefined') && !!(window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB);
Module['INITIAL_MEMORY'] = CUSTOM_PARAMETERS.custom_heap_size;
Module['onRuntimeInitialized'] = function() {
Module.runApp("canvas");
};
Module["locateFile"] = function(path, scriptDirectory)
{
// dmengine*.wasm is hardcoded in the built JS loader for WASM,
// we need to replace it here with the correct project name.
if (path == "dmengine.wasm" || path == "dmengine_release.wasm" || path == "dmengine_headless.wasm") {
path = "Druid.wasm";
}
return scriptDirectory + path;
};
window.onerror = function(err, url, line, column, errObj) {
if (typeof Module.ccall !== 'undefined') {
var errorObject = Module.prepareErrorObject(err, url, line, column, errObj);