181 lines
6.6 KiB
JavaScript
181 lines
6.6 KiB
JavaScript
/*
|
|
* Copyright (c) 2024 lax1dude. All Rights Reserved.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
addToLibrary({
|
|
getJSPISupported: function() {
|
|
return (typeof WebAssembly.Suspending !== "undefined");
|
|
},
|
|
getEPWLength: function() {
|
|
return epwFile.byteLength;
|
|
},
|
|
memcpyFromEPW: function(dest, off, len) {
|
|
HEAPU8.set(new Uint8Array(epwFile, off, len), dest);
|
|
},
|
|
initResult: function(bufLen) {
|
|
const id = results.length;
|
|
results.push(new Uint8Array(bufLen));
|
|
return id;
|
|
},
|
|
memcpyToResult: function(bufId, src, off, len) {
|
|
results[bufId].set(new Uint8Array(HEAPU8.buffer, src, len), off);
|
|
},
|
|
memcpyFromEPWToResult: function(bufId, dest, off, len) {
|
|
results[bufId].set(new Uint8Array(epwFile, off, len), dest);
|
|
},
|
|
initEPWStringResult: function(off, len) {
|
|
const id = results.length;
|
|
results.push(UTF8Decoder.decode(new Uint8Array(epwFile, off, len)));
|
|
return id;
|
|
},
|
|
resultFailed: function(msg) {
|
|
const parentElement = createCrashParentElement();
|
|
|
|
const messageContainer = document.createElement("div");
|
|
messageContainer.setAttribute("style", "z-index:100;position:absolute;top:10%;left:10%;right:10%;bottom:10%;background-color:white;border:2px solid #cccccc;overflow-x:hidden;overflow-y:scroll;");
|
|
messageContainer.classList.add("_eaglercraftX_loader_failed_container");
|
|
|
|
const failMsg = UTF8ToString(msg);
|
|
console.error("LoaderMain: [FAILED] " + failMsg);
|
|
|
|
const failureMsgElement = document.createElement("h2");
|
|
failureMsgElement.style.color = "#AA0000";
|
|
failureMsgElement.style.padding = "25px";
|
|
failureMsgElement.style.fontFamily = "sans-serif";
|
|
failureMsgElement.style["marginBlock"] = "0px";
|
|
failureMsgElement.appendChild(document.createTextNode(failMsg));
|
|
messageContainer.appendChild(failureMsgElement);
|
|
|
|
const failureMsgElement2 = document.createElement("h4");
|
|
failureMsgElement2.style.color = "#AA0000";
|
|
failureMsgElement2.style.padding = "25px";
|
|
failureMsgElement2.style.fontFamily = "sans-serif";
|
|
failureMsgElement2.style["marginBlock"] = "0px";
|
|
failureMsgElement2.appendChild(document.createTextNode("Try again later"));
|
|
messageContainer.appendChild(failureMsgElement2);
|
|
|
|
parentElement.appendChild(messageContainer);
|
|
},
|
|
resultSuccess: function(result) {
|
|
const idx = result >> 2;
|
|
|
|
const eagRuntimeJSURL = URL.createObjectURL(new Blob([results[HEAP32[idx]]], { type: "text/javascript;charset=utf-8" }));
|
|
const classesWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 1]]], { type: "application/wasm" }));
|
|
const classesDeobfTEADBGURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 2]]], { type: "application/octet-stream" }));
|
|
const classesDeobfWASMURL = URL.createObjectURL(new Blob([results[HEAP32[idx + 3]]], { type: "application/wasm" }));
|
|
|
|
const pressAnyKey = URL.createObjectURL(new Blob([results[HEAP32[idx + 4]]], { type: results[HEAP32[idx + 5]] }));
|
|
const crashImg = URL.createObjectURL(new Blob([results[HEAP32[idx + 6]]], { type: results[HEAP32[idx + 7]] }));
|
|
const faviconImg = URL.createObjectURL(new Blob([results[HEAP32[idx + 8]]], { type: results[HEAP32[idx + 9]] }));
|
|
|
|
const numEPKs = HEAP32[idx + 10];
|
|
const epkFiles = new Array(numEPKs);
|
|
for(var i = 0, j; i < numEPKs; ++i) {
|
|
j = idx + 11 + i * 3;
|
|
epkFiles[i] = {
|
|
data: results[HEAP32[j]],
|
|
name: results[HEAP32[j + 1]],
|
|
path: results[HEAP32[j + 2]]
|
|
};
|
|
}
|
|
|
|
results.length = 0;
|
|
|
|
window.__eaglercraftXLoaderContext = {
|
|
getEaglercraftXOpts: function() {
|
|
return optsObj;
|
|
},
|
|
getEagRuntimeJSURL: function() {
|
|
return eagRuntimeJSURL;
|
|
},
|
|
getClassesWASMURL: function() {
|
|
return classesWASMURL;
|
|
},
|
|
getClassesDeobfWASMURL: function() {
|
|
return classesDeobfWASMURL;
|
|
},
|
|
getClassesTEADBGURL: function() {
|
|
return classesDeobfTEADBGURL;
|
|
},
|
|
getEPKFiles: function() {
|
|
return epkFiles;
|
|
},
|
|
getRootElement: function() {
|
|
return rootElement;
|
|
},
|
|
getMainArgs: function() {
|
|
return [];
|
|
},
|
|
getImageURL: function(idx) {
|
|
switch(idx) {
|
|
case 0:
|
|
return splashURL;
|
|
case 1:
|
|
return pressAnyKey;
|
|
case 2:
|
|
return crashImg;
|
|
case 3:
|
|
return faviconImg;
|
|
default:
|
|
return null;
|
|
}
|
|
},
|
|
runMain: function(fn) {
|
|
setTimeout(fn, 10);
|
|
}
|
|
};
|
|
|
|
const scriptElement = document.createElement("script");
|
|
scriptElement.type = "text/javascript";
|
|
scriptElement.src = eagRuntimeJSURL;
|
|
document.head.appendChild(scriptElement);
|
|
},
|
|
resultJSPIUnsupported: function(result) {
|
|
const idx = result >> 2;
|
|
|
|
const crashImgData = results[HEAP32[idx]];
|
|
const crashImgMIME = results[HEAP32[idx + 1]];
|
|
const crashImg = crashImgData ? URL.createObjectURL(new Blob([crashImgData], { type: (crashImgMIME || "image/png") })) : null;
|
|
|
|
const markupData = results[HEAP32[idx + 2]];
|
|
const markup = markupData ? UTF8Decoder.decode(markupData) : "<h1>Failed to load error screen</h1>";
|
|
|
|
const parentElement = createCrashParentElement();
|
|
|
|
const img = document.createElement("img");
|
|
img.setAttribute("style", "z-index:100;position:absolute;top:10px;left:calc(50% - 151px);");
|
|
img.src = crashImg;
|
|
parentElement.appendChild(img);
|
|
|
|
const iframeContainer = document.createElement("div");
|
|
iframeContainer.setAttribute("style", "z-index:100;position:absolute;top:135px;left:10%;right:10%;bottom:50px;background-color:white;border:2px solid #cccccc;");
|
|
iframeContainer.classList.add("_eaglercraftX_jspi_unsupported_container");
|
|
|
|
const iframe = document.createElement("iframe");
|
|
iframe.classList.add("_eaglercraftX_jspi_unsupported_frame");
|
|
iframe.setAttribute("style", "border:none;width:100%;height:100%;");
|
|
iframe.srcdoc = markup;
|
|
|
|
iframeContainer.appendChild(iframe);
|
|
parentElement.appendChild(iframeContainer);
|
|
},
|
|
dbgLog: function(msg) {
|
|
console.log("LoaderMain: [INFO] " + UTF8ToString(msg));
|
|
},
|
|
dbgErr: function(msg) {
|
|
console.error("LoaderMain: [ERROR] " + UTF8ToString(msg));
|
|
}
|
|
});
|