You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
434 lines
12 KiB
Plaintext
434 lines
12 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>%GAME%</title>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=2">
|
|
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
|
|
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
|
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
|
|
</head>
|
|
<body>
|
|
|
|
<style type="text/css">
|
|
|
|
html, body, .container {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
font-family: "Helvetica Neue", "HelveticaNeue", Helvetica, Arial, sans-serif;
|
|
}
|
|
|
|
.h4, h4{
|
|
margin-top: 1pt;
|
|
margin-bottom: 1pt;
|
|
font-size: 10pt;
|
|
}
|
|
|
|
.container {
|
|
display: table;
|
|
vertical-align: middle;
|
|
border: 0px;
|
|
border-spacing: 0px;
|
|
}
|
|
|
|
.glyphicon-spin {
|
|
animation: spin 2000ms infinite linear;
|
|
}
|
|
|
|
@keyframes spin {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: rotate(359deg);
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes spin {
|
|
0% {
|
|
transform: rotate(0deg);
|
|
}
|
|
100% {
|
|
transform: rotate(359deg);
|
|
}
|
|
}
|
|
|
|
.emscripten{
|
|
max-height: 60%;
|
|
max-height: 60vh;
|
|
min-height: 60%;
|
|
min-height: 60vh;
|
|
|
|
align-items: center;
|
|
position: relative;
|
|
margin: 0px;
|
|
text-align: center;
|
|
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
.texthalf {
|
|
height: 37%;
|
|
border: 0px;
|
|
padding: 0px;
|
|
overflow-y: scroll;
|
|
font-size: 2em;
|
|
}
|
|
|
|
.buttonarea {
|
|
min-height: 3%;
|
|
border-top: 0px;
|
|
border-bottom: 0px;
|
|
padding: 0px;
|
|
margin-right: 0px;
|
|
margin-top: 0px;
|
|
margin-bottom: 0px;
|
|
}
|
|
|
|
.btn {padding: 0px; text-align: center; min-width:150px }
|
|
.progress {background: rgba(245, 245, 245, 1); border: 0px solid rgba(245, 245, 245, 1); border-radius: 0px; height: 4px;}
|
|
.progress-bar-custom {background: rgba(153, 153, 153, 1);}
|
|
|
|
#progressbar { width: 50%; margin: 0 auto;}
|
|
|
|
</style>
|
|
|
|
<script type="text/javascript">
|
|
|
|
function addLog(info, color) {
|
|
$( "#logwindow" ).append( "<h4><small>" + info + " </small></h4>");
|
|
}
|
|
|
|
// combine all parallel downloads into one progress bar.
|
|
var totalDownloadSize = 0;
|
|
var currentDownloadedSize = 0;
|
|
|
|
function download(urlName) {
|
|
|
|
addLog( "Starting download " + urlName );
|
|
|
|
return $.ajax({
|
|
url: urlName,
|
|
dataType: "text",
|
|
success: function(scriptText){
|
|
// insert into dom - this bit is tricky, standard way makes asm.js complain about caching.
|
|
// use a blob object.
|
|
var scriptblob = new Blob([scriptText], { type: 'text/javascript' });
|
|
|
|
var script = document.createElement('script');
|
|
script.src = URL.createObjectURL(scriptblob);
|
|
|
|
script.onload = function() {
|
|
// we are done.
|
|
URL.revokeObjectURL(script.src);
|
|
};
|
|
document.body.appendChild(script);
|
|
addLog ( urlName + " downloaded ");
|
|
},
|
|
xhrFields: {
|
|
totaladded : false,
|
|
lastloadedsize: 0,
|
|
onprogress: function (e) {
|
|
if (e.lengthComputable) {
|
|
|
|
if (!this.totaladded) {
|
|
totalDownloadSize += e.total;
|
|
if ( e.total > 20*1024*1024){
|
|
addLog("possibly downloading uncompressed javascript, please host compressed javascript when in production");
|
|
}
|
|
this.totaladded = true;
|
|
}
|
|
|
|
var deltasize = e.loaded - this.lastloadedsize;
|
|
currentDownloadedSize += deltasize;
|
|
this.lastloadedsize = e.loaded;
|
|
|
|
var percentage = (currentDownloadedSize / totalDownloadSize * 100);
|
|
|
|
// update progress bar.
|
|
$('.progress-bar-custom').css('width', percentage+'%').attr('aria-valuenow', percentage);
|
|
}else {
|
|
console.log ("wierd, couldn't get size");
|
|
}
|
|
},
|
|
onload: function(e){
|
|
// empty.
|
|
}
|
|
}
|
|
});
|
|
};
|
|
|
|
// helper functions.
|
|
// http://stackoverflow.com/questions/4750015/regular-expression-to-find-urls-within-a-string
|
|
function getHTMLGetParam(name){
|
|
if(name=(new RegExp('[?&]'+encodeURIComponent(name)+'=([^&]*)')).exec(location.search))
|
|
return decodeURIComponent(name[1]);
|
|
}
|
|
|
|
var filehostargument = " ";
|
|
|
|
// we are serving via a server and it is unreal file server.
|
|
if ( location.host != "" && getHTMLGetParam("cookonthefly") == "true" )
|
|
{
|
|
filehostargument = "' -filehostIp=http://" + location.host + " '";
|
|
}
|
|
|
|
var UE4 = {
|
|
get resize_game() {
|
|
var fn = Module.cwrap('resize_game', null, ['number'],['number'] );
|
|
delete UE4["resize_game"];
|
|
UE4.resize_game = fn;
|
|
return fn;
|
|
}
|
|
,
|
|
get on_fatal() {
|
|
try {
|
|
var fn = Module.cwrap('on_fatal', null, ['string', 'string'])
|
|
delete UE4["on_fatal"];
|
|
UE4.on_fatal = fn;
|
|
return fn;
|
|
} catch(e) {
|
|
return function() {}
|
|
}
|
|
},
|
|
};
|
|
|
|
//http://www.browserleaks.com/webgl#howto-detect-webgl
|
|
function webgl_detect()
|
|
{
|
|
if (!!window.WebGLRenderingContext) {
|
|
var canvas = document.createElement("canvas"),
|
|
names = ["webgl", "experimental-webgl", "moz-webgl", "webkit-3d"],
|
|
context = false;
|
|
|
|
for(var i=0;i<4;i++) {
|
|
try {
|
|
context = canvas.getContext(names[i]);
|
|
if (context && typeof context.getParameter == "function") {
|
|
// WebGL is enabled
|
|
return true;
|
|
}
|
|
} catch(e) {}
|
|
}
|
|
// WebGL is supported, but disabled
|
|
return false;
|
|
}
|
|
// WebGL not supported
|
|
return false;
|
|
}
|
|
|
|
function isBrowser64Bit() {
|
|
var userAgent = window.navigator.userAgent;
|
|
// if we are windows and runningas as WOW64 ( windows on windows 64 ) or Win32 we are a 32 bit browser.
|
|
if ( userAgent.indexOf ("Windows") > -1 && ( userAgent.indexOf("WOW64") > -1 || userAgent.indexOf("Win32") > -1 ))
|
|
return false;
|
|
// all other platforms and browsers - assume 64 bit.
|
|
return true;
|
|
}
|
|
|
|
// generated from game.template
|
|
// note: Packaging process looks at HTML5Engine.ini to pick up values.
|
|
var TOTAL_GAME_MEMORY = %HEAPSIZE%;
|
|
|
|
// check max memory usage, we need to clamp it down for 32 bit browsers.
|
|
if (!isBrowser64Bit()) {
|
|
var max_32bit_browser_memory = 512 * 1024 * 1024 ; // using a reasonable number, this number can change depending on the memory pressure from the underlying OS and whether or not it can give a contiguous block of 512 MB memory to a 32 bit process.
|
|
if ( TOTAL_GAME_MEMORY > max_32bit_browser_memory ){
|
|
console.log (" Current Browser : " + window.navigator.userAgent );
|
|
console.log ( "We are running in 32 bit browser, clamping requested memory size of " + TOTAL_GAME_MEMORY + " bytes to " +max_32bit_browser_memory);
|
|
TOTAL_GAME_MEMORY = max_32bit_browser_memory;
|
|
}
|
|
}
|
|
|
|
// setup global error handling.
|
|
// make exceptions more visible.
|
|
window.onerror = function(msg, url, line, column, error) {
|
|
UE4.on_fatal(msg, error);
|
|
|
|
// remove everything.
|
|
$('#mainarea').empty();
|
|
// add alert!
|
|
|
|
// clean up the message.
|
|
msg = msg.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
|
$ ('#mainarea').append ( '<div class="alert alert-danger text-left" style ="min-height: 10px; z-index: 2" role="alert" ><h4><small>' + msg + '</small></h4></div>');
|
|
|
|
if ( msg.indexOf("memory") > -1 ) {
|
|
var message = !isBrowser64Bit() ? " We are running on a 32 bit browser, please use a 64 bit browser to avoid memory constraints "
|
|
: " Looks like the game needs more than the allocated " + TOTAL_GAME_MEMORY + " bytes, please edit HTML5Engine.ini and repackage ";
|
|
console.log(message);
|
|
}
|
|
};
|
|
|
|
function preInitEmscripten(){
|
|
|
|
// add canvas but to the dom but don't show it yet.
|
|
$ ('<canvas>').
|
|
attr({
|
|
id : "canvas",
|
|
class: "emscripten",
|
|
oncontextmenu : "event.preventDefault()",
|
|
height: 904,
|
|
width: 1600,
|
|
}).appendTo('#mainarea').hide();
|
|
|
|
// setup emscripten's canvas.
|
|
Module['canvas'] = document.getElementById('canvas');
|
|
|
|
}
|
|
|
|
function preRunEmscripten() {
|
|
}
|
|
|
|
|
|
function postRunEmscripten() {
|
|
// remove compiling message.
|
|
$("#compilingmessage").remove();
|
|
// it still takes couple of ticks after run before anything can be drawn. show the canvas at the last possible moment.
|
|
$("#canvas").show();
|
|
}
|
|
|
|
// create a deffered object for the data file.
|
|
var dataFileDeferredObject = new $.Deferred();
|
|
|
|
// main emscripten module.
|
|
var Module = {
|
|
|
|
preInit: [preInitEmscripten],
|
|
preRun: [preRunEmscripten],
|
|
postRun: [postRunEmscripten],
|
|
|
|
TOTAL_MEMORY: TOTAL_GAME_MEMORY,
|
|
noImageDecoding: true,
|
|
noAudioDecoding: true,
|
|
arguments: [%UE4CMDLINE%,filehostargument],
|
|
|
|
print: (function() {
|
|
return addLog;
|
|
})(),
|
|
|
|
printErr: function(text) {
|
|
console.log(text);
|
|
},
|
|
|
|
// state management
|
|
infoPrinted: false,
|
|
lastcurrentDownloadedSize: 0,
|
|
|
|
// packaged data download, sets this information.
|
|
setStatus: function(text) {
|
|
var matches = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
|
|
|
if (matches == null){
|
|
addLog(text);
|
|
return;
|
|
}
|
|
|
|
if (!this.infoPrinted) {
|
|
for(var download in this.dataFileDownloads){
|
|
addLog(" starting download " + download + " [Packaged data]");
|
|
// add to total size.
|
|
totalDownloadSize += parseInt(matches[4]);
|
|
}
|
|
this.infoPrinted = true;
|
|
}
|
|
|
|
currentDownloadedSize += (parseInt(matches[2]) - this.lastcurrentDownloadedSize);
|
|
this.lastcurrentDownloadedSize = parseInt(matches[2]);
|
|
|
|
|
|
var percentage = currentDownloadedSize/totalDownloadSize * 100;
|
|
$('.progress-bar-custom').css('width', percentage+'%').attr('aria-valuenow', percentage);
|
|
|
|
if (matches[2] == matches[4]){
|
|
// lets resolve our deffered object
|
|
dataFileDeferredObject.resolve ( "Data file download finished");
|
|
|
|
for(var download in this.dataFileDownloads){
|
|
addLog( download + " downloaded ")
|
|
}
|
|
}
|
|
},
|
|
|
|
totalDependencies: 0,
|
|
monitorRunDependencies: function(left) {
|
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
|
}
|
|
};
|
|
|
|
$(document).ready(function() {
|
|
|
|
// check for webgl.
|
|
if(!webgl_detect()) {
|
|
$ ('#mainarea').empty();
|
|
$ ('#mainarea').append ( '<div class="alert alert-danger" style ="min-height: 10pt" role="alert"><a href="https://get.webgl.org/" class="alert-link">WebGL Not Detected!</a></div></div>');
|
|
return;
|
|
}
|
|
|
|
addLog( "Starting downloads" );
|
|
// start downloads in parallel, print when done.
|
|
var promises = [
|
|
'json2.js',
|
|
'jStorage.js',
|
|
'moz_binarystring.js',
|
|
'%GAME%.data.js',
|
|
'%CONFIG%.js'
|
|
].map(download);
|
|
|
|
// add the data file promise.
|
|
promises.push(dataFileDeferredObject.promise());
|
|
|
|
$.when.apply(undefined,
|
|
promises
|
|
).then( function(){
|
|
// all javascript downloads are complete.
|
|
// all data file downloads are complete too.
|
|
|
|
// at this point the only stuff is remaining it compilation and execution.
|
|
// remove progress bar.
|
|
$("#progressbar").remove();
|
|
|
|
// insert info about compiling;
|
|
|
|
$ ('#mainarea').append ( '<div class="alert alert-warning" style ="min-height: 20px" role="alert" id="compilingmessage"><span class="glyphicon glyphicon-refresh glyphicon-spin"></span> Compiling</div>');
|
|
addLog ("all downloads complete ");
|
|
},
|
|
function(){
|
|
|
|
$('#progressbar').remove();
|
|
$ ('#mainarea').append ( '<div class="alert alert-danger" style ="min-height: 20px" role="alert">One or more downloads failed! Please refresh this page</div>');
|
|
|
|
addLog("Download failed");
|
|
}
|
|
);
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
<div class="emscripten" id= "mainarea">
|
|
<div class="progress" id = "progressbar">
|
|
<div class="progress-bar progress-bar-custom"
|
|
role="progressbar"
|
|
aria-valuenow="0"
|
|
aria-valuemin="0"
|
|
aria-valuemax="100"
|
|
style="width: 0%; "
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row buttonarea text-center" id="buttonrow">
|
|
<div class="col-sm-2 text-center"></div>
|
|
<div class="col-sm-2 text-center"><button type="button" class="btn btn-primary" onclick="Module['pauseMainLoop']();" >Pause</button></div>
|
|
<div class="col-sm-2 text-center"><button type="button" class="btn btn-primary" onclick="Module['resumeMainLoop']();" >Resume</button></div>
|
|
<div class="col-sm-2 text-center"><button type="button" class="btn btn-primary" onclick="$.jStorage.flush()">Clear Stored Game</button></div>
|
|
<div class="col-sm-2 text-center"><button type="button" class="btn btn-primary" id="fullscreen_request" >FullScreen</button></div>
|
|
<div class="col-sm-2 text-center"></div>
|
|
</div>
|
|
<div class="texthalf text-normal jumbotron" id="logwindow"></div>
|
|
</div>
|
|
</body>
|
|
</html> |