61026e62bf
Whether to use WebGL 1.0 or 2.0 can only be determined at runtime after reading project settings, so check for the lower version. The test is now in the HTML file, so if desired WebGL 2.0 can be checked early by changing the behaviour there.
391 lines
10 KiB
HTML
391 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<title></title>
|
|
<style type="text/css">
|
|
|
|
body {
|
|
margin: 0;
|
|
border: 0 none;
|
|
padding: 0;
|
|
text-align: center;
|
|
background-color: #222226;
|
|
font-family: 'Noto Sans', Arial, sans-serif;
|
|
}
|
|
|
|
|
|
/* Godot Engine default theme style
|
|
* ================================ */
|
|
|
|
.godot {
|
|
color: #e0e0e0;
|
|
background-color: #3b3943;
|
|
background-image: linear-gradient(to bottom, #403e48, #35333c);
|
|
border: 1px solid #45434e;
|
|
box-shadow: 0 0 1px 1px #2f2d35;
|
|
}
|
|
|
|
button.godot {
|
|
font-family: 'Droid Sans', Arial, sans-serif; /* override user agent style */
|
|
padding: 1px 5px;
|
|
background-color: #37353f;
|
|
background-image: linear-gradient(to bottom, #413e49, #3a3842);
|
|
border: 1px solid #514f5d;
|
|
border-radius: 1px;
|
|
box-shadow: 0 0 1px 1px #2a2930;
|
|
}
|
|
|
|
button.godot:hover {
|
|
color: #f0f0f0;
|
|
background-color: #44414e;
|
|
background-image: linear-gradient(to bottom, #494652, #423f4c);
|
|
border: 1px solid #5a5667;
|
|
box-shadow: 0 0 1px 1px #26252b;
|
|
}
|
|
|
|
button.godot:active {
|
|
color: #fff;
|
|
background-color: #3e3b46;
|
|
background-image: linear-gradient(to bottom, #36343d, #413e49);
|
|
border: 1px solid #4f4c59;
|
|
box-shadow: 0 0 1px 1px #26252b;
|
|
}
|
|
|
|
button.godot:disabled {
|
|
color: rgba(230, 230, 230, 0.2);
|
|
background-color: #3d3d3d;
|
|
background-image: linear-gradient(to bottom, #434343, #393939);
|
|
border: 1px solid #474747;
|
|
box-shadow: 0 0 1px 1px #2d2b33;
|
|
}
|
|
|
|
|
|
/* Canvas / wrapper
|
|
* ================ */
|
|
|
|
#container {
|
|
display: inline-block; /* scale with canvas */
|
|
vertical-align: top; /* prevent extra height */
|
|
position: relative; /* root for absolutely positioned overlay */
|
|
margin: 0;
|
|
border: 0 none;
|
|
padding: 0;
|
|
background-color: #0c0c0c;
|
|
}
|
|
|
|
#canvas {
|
|
display: block;
|
|
margin: 0 auto;
|
|
color: white;
|
|
}
|
|
|
|
#canvas:focus {
|
|
outline: none;
|
|
}
|
|
|
|
|
|
/* Status display
|
|
* ============== */
|
|
|
|
#status {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
/* don't consume click events - make children visible explicitly */
|
|
visibility: hidden;
|
|
}
|
|
|
|
#status-progress {
|
|
width: 244px;
|
|
height: 7px;
|
|
background-color: #38363A;
|
|
border: 1px solid #444246;
|
|
padding: 1px;
|
|
box-shadow: 0 0 2px 1px #1B1C22;
|
|
border-radius: 2px;
|
|
visibility: visible;
|
|
}
|
|
|
|
#status-progress-inner {
|
|
height: 100%;
|
|
width: 0;
|
|
box-sizing: border-box;
|
|
transition: width 0.5s linear;
|
|
background-color: #202020;
|
|
border: 1px solid #222223;
|
|
box-shadow: 0 0 1px 1px #27282E;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
#status-indeterminate {
|
|
visibility: visible;
|
|
position: relative;
|
|
}
|
|
|
|
#status-indeterminate > div {
|
|
width: 3px;
|
|
height: 0;
|
|
border-style: solid;
|
|
border-width: 6px 2px 0 2px;
|
|
border-color: #2b2b2b transparent transparent transparent;
|
|
transform-origin: center 14px;
|
|
position: absolute;
|
|
}
|
|
|
|
#status-indeterminate > div:nth-child(1) { transform: rotate( 22.5deg); }
|
|
#status-indeterminate > div:nth-child(2) { transform: rotate( 67.5deg); }
|
|
#status-indeterminate > div:nth-child(3) { transform: rotate(112.5deg); }
|
|
#status-indeterminate > div:nth-child(4) { transform: rotate(157.5deg); }
|
|
#status-indeterminate > div:nth-child(5) { transform: rotate(202.5deg); }
|
|
#status-indeterminate > div:nth-child(6) { transform: rotate(247.5deg); }
|
|
#status-indeterminate > div:nth-child(7) { transform: rotate(292.5deg); }
|
|
#status-indeterminate > div:nth-child(8) { transform: rotate(337.5deg); }
|
|
|
|
#status-notice {
|
|
margin: 0 100px;
|
|
line-height: 1.3;
|
|
visibility: visible;
|
|
padding: 4px 6px;
|
|
visibility: visible;
|
|
}
|
|
|
|
|
|
/* Debug output
|
|
* ============ */
|
|
|
|
#output-panel {
|
|
display: none;
|
|
max-width: 700px;
|
|
font-size: small;
|
|
margin: 6px auto 0;
|
|
padding: 0 4px 4px;
|
|
text-align: left;
|
|
line-height: 2.2;
|
|
}
|
|
|
|
#output-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
#output-container {
|
|
padding: 6px;
|
|
background-color: #2c2a32;
|
|
box-shadow: inset 0 0 1px 1px #232127;
|
|
color: #bbb;
|
|
}
|
|
|
|
#output-scroll {
|
|
line-height: 1;
|
|
height: 12em;
|
|
overflow-y: scroll;
|
|
white-space: pre-wrap;
|
|
font-size: small;
|
|
font-family: "Lucida Console", Monaco, monospace;
|
|
}
|
|
</style>
|
|
$GODOT_HEAD_INCLUDE
|
|
</head>
|
|
<body>
|
|
<div id="container">
|
|
<canvas id="canvas" oncontextmenu="event.preventDefault();" width="640" height="480">
|
|
HTML5 canvas appears to be unsupported in the current browser.<br />
|
|
Please try updating or use a different browser.
|
|
</canvas>
|
|
<div id="status">
|
|
<div id='status-progress' style='display: none;' oncontextmenu="event.preventDefault();"><div id ='status-progress-inner'></div></div>
|
|
<div id='status-indeterminate' style='display: none;' oncontextmenu="event.preventDefault();">
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
<div></div>
|
|
</div>
|
|
<div id="status-notice" class="godot" style='display: none;'></div>
|
|
</div>
|
|
</div>
|
|
<div id="output-panel" class="godot">
|
|
<div id="output-header">
|
|
Output:
|
|
<button id='output-clear' class='godot' type='button' autocomplete='off'>Clear</button>
|
|
</div>
|
|
<div id="output-container"><div id="output-scroll"></div></div>
|
|
</div>
|
|
|
|
<script type="text/javascript" src="$GODOT_BASENAME.js"></script>
|
|
<script type="text/javascript">//<![CDATA[
|
|
|
|
var engine = new Engine;
|
|
|
|
(function() {
|
|
|
|
const BASENAME = '$GODOT_BASENAME';
|
|
const DEBUG_ENABLED = $GODOT_DEBUG_ENABLED;
|
|
const INDETERMINATE_STATUS_STEP_MS = 100;
|
|
|
|
var container = document.getElementById('container');
|
|
var canvas = document.getElementById('canvas');
|
|
var statusProgress = document.getElementById('status-progress');
|
|
var statusProgressInner = document.getElementById('status-progress-inner');
|
|
var statusIndeterminate = document.getElementById('status-indeterminate');
|
|
var statusNotice = document.getElementById('status-notice');
|
|
|
|
var initializing = true;
|
|
var statusMode = 'hidden';
|
|
var indeterminiateStatusAnimationId = 0;
|
|
|
|
function setStatusMode(mode) {
|
|
|
|
if (statusMode === mode || !initializing)
|
|
return;
|
|
[statusProgress, statusIndeterminate, statusNotice].forEach(elem => {
|
|
elem.style.display = 'none';
|
|
});
|
|
if (indeterminiateStatusAnimationId !== 0) {
|
|
cancelAnimationFrame(indeterminiateStatusAnimationId);
|
|
indeterminiateStatusAnimationId = 0;
|
|
}
|
|
switch (mode) {
|
|
case 'progress':
|
|
statusProgress.style.display = 'block';
|
|
break;
|
|
case 'indeterminate':
|
|
statusIndeterminate.style.display = 'block';
|
|
indeterminiateStatusAnimationId = requestAnimationFrame(animateStatusIndeterminate);
|
|
break;
|
|
case 'notice':
|
|
statusNotice.style.display = 'block';
|
|
break;
|
|
case 'hidden':
|
|
break;
|
|
default:
|
|
throw new Error("Invalid status mode");
|
|
}
|
|
statusMode = mode;
|
|
}
|
|
|
|
function animateStatusIndeterminate(ms) {
|
|
var i = Math.floor(ms / INDETERMINATE_STATUS_STEP_MS % 8);
|
|
if (statusIndeterminate.children[i].style.borderTopColor == '') {
|
|
Array.prototype.slice.call(statusIndeterminate.children).forEach(child => {
|
|
child.style.borderTopColor = '';
|
|
});
|
|
statusIndeterminate.children[i].style.borderTopColor = '#dfdfdf';
|
|
}
|
|
requestAnimationFrame(animateStatusIndeterminate);
|
|
}
|
|
|
|
function setStatusNotice(text) {
|
|
|
|
while (statusNotice.lastChild) {
|
|
statusNotice.removeChild(statusNotice.lastChild);
|
|
}
|
|
var lines = text.split('\n');
|
|
lines.forEach((line, index) => {
|
|
statusNotice.appendChild(document.createTextNode(line));
|
|
statusNotice.appendChild(document.createElement('br'));
|
|
});
|
|
};
|
|
|
|
engine.setProgressFunc((current, total) => {
|
|
|
|
if (total > 0) {
|
|
statusProgressInner.style.width = current/total * 100 + '%';
|
|
setStatusMode('progress');
|
|
if (current === total) {
|
|
// wait for progress bar animation
|
|
setTimeout(() => {
|
|
setStatusMode('indeterminate');
|
|
}, 500);
|
|
}
|
|
} else {
|
|
setStatusMode('indeterminate');
|
|
}
|
|
});
|
|
|
|
if (DEBUG_ENABLED) {
|
|
var outputRoot = document.getElementById("output-panel");
|
|
var outputScroll = document.getElementById("output-scroll");
|
|
var OUTPUT_MSG_COUNT_MAX = 400;
|
|
|
|
document.getElementById('output-clear').addEventListener('click', () => {
|
|
while (outputScroll.firstChild) {
|
|
outputScroll.firstChild.remove();
|
|
}
|
|
});
|
|
|
|
outputRoot.style.display = 'block';
|
|
|
|
function print(text) {
|
|
while (outputScroll.childElementCount >= OUTPUT_MSG_COUNT_MAX) {
|
|
outputScroll.firstChild.remove();
|
|
}
|
|
var msg = document.createElement("div");
|
|
if (String.prototype.trim.call(text).startsWith("**ERROR**")) {
|
|
msg.style.color = "#d44";
|
|
} else if (String.prototype.trim.call(text).startsWith("**WARNING**")) {
|
|
msg.style.color = "#ccc000";
|
|
} else if (String.prototype.trim.call(text).startsWith("**SCRIPT ERROR**")) {
|
|
msg.style.color = "#c6d";
|
|
}
|
|
msg.textContent = text;
|
|
var scrollToBottom = outputScroll.scrollHeight - (outputScroll.clientHeight + outputScroll.scrollTop) < 10;
|
|
outputScroll.appendChild(msg);
|
|
if (scrollToBottom) {
|
|
outputScroll.scrollTop = outputScroll.scrollHeight;
|
|
}
|
|
};
|
|
|
|
function printError(text) {
|
|
if (!String.prototype.trim.call(text).startsWith('**ERROR**: ')) {
|
|
text = '**ERROR**: ' + text;
|
|
}
|
|
print(text);
|
|
}
|
|
|
|
engine.setStdoutFunc(text => {
|
|
print(text);
|
|
console.log(text);
|
|
});
|
|
|
|
engine.setStderrFunc(text => {
|
|
printError(text);
|
|
console.warn(text);
|
|
});
|
|
}
|
|
|
|
function displayFailureNotice(err) {
|
|
var msg = err.message || err;
|
|
if (DEBUG_ENABLED) {
|
|
printError(msg);
|
|
}
|
|
console.error(msg);
|
|
setStatusNotice(msg);
|
|
setStatusMode('notice');
|
|
initializing = false;
|
|
};
|
|
|
|
if (!Engine.isWebGLAvailable()) {
|
|
displayFailureNotice("WebGL not available");
|
|
} else {
|
|
setStatusMode('indeterminate');
|
|
engine.setCanvas(canvas);
|
|
engine.startGame(BASENAME + '.pck').then(() => {
|
|
setStatusMode('hidden');
|
|
initializing = false;
|
|
}, displayFailureNotice);
|
|
}
|
|
})();
|
|
//]]></script>
|
|
</body>
|
|
</html>
|