2014-08-25 07:35:41 +00:00
<!doctype html>
< html lang = "en-us" >
< head >
2021-10-22 22:27:58 +00:00
< meta charset = "utf-8" >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" >
2014-09-02 06:16:33 +00:00
< meta name = viewport content = "width=device-width, initial-scale=1" >
2021-10-22 22:27:58 +00:00
< title > FTE QuakeWorld< / title >
< style >
2017-07-31 17:15:37 +00:00
html,body { background-color:#000000; color:#808080; height:100%;width:100%;margin:0;padding:0;}
2015-08-07 17:49:49 +00:00
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
div.emscripten { text-align: center; padding:0; margin: 0;}
/* the canvas *must not* have any border or padding, or mouse coords will be wrong */
canvas.emscripten { border: 0px none; width:100%; height:100%; padding:0; margin: 0;}
2021-10-22 22:27:58 +00:00
< / style >
2014-08-25 07:35:41 +00:00
< / head >
2021-10-22 22:27:58 +00:00
< body ondrop = "gotdrop(event);" ondragover = "event.preventDefault()" >
< div class = "emscripten" id = "status" > Please allow/unblock our javascript to play.< / div >
< div id = "dropzone" ondrop = "gotdrop(event);" ondragover = "event.preventDefault()" hidden = 1 > Drop Zone< / div >
< button type = "button" onclick = "begin()" id = "begin" hidden = 1 > Click To Begin!< / button >
< div class = "emscripten" >
< progress value = "0" max = "100" id = "progress" hidden = 1 > < / progress >
< / div >
< canvas class = "emscripten" id = "canvas" oncontextmenu = "event.preventDefault()" hidden = 1 > < / canvas >
< script type = 'text/javascript' >
2015-08-07 17:49:49 +00:00
// connect to canvas
var Module = {
2021-10-22 22:27:58 +00:00
files:
{ //these can be arraybuffers(you'll need a helper to define those) or promises(fte will block till they complete), or strings (which will be interpretted as urls and downloaded before any C code is run)
//note that the code below will skip the file-drop prompt if there's any files specified here (or there's a #foo.fmf file specified)
// "default.fmf": "default.fmf",
// "id1/pak0.pak": "pak0.pak",
},
2015-08-07 17:49:49 +00:00
print: function(msg)
2021-10-22 22:27:58 +00:00
{ //stdout...
2015-08-07 17:49:49 +00:00
console.log(msg);
},
printErr: function(text)
2021-10-22 22:27:58 +00:00
{ //stderr...
console.log(text);
2015-08-07 17:49:49 +00:00
},
2021-10-22 22:27:58 +00:00
canvas: document.getElementById('canvas'), //for webgl to attach to
setStatus: function(text)
{ //gets spammed some prints during startup. blame emscripten.
2015-08-07 17:49:49 +00:00
if (Module.setStatus.interval)
clearInterval(Module.setStatus.interval);
var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
var statusElement = document.getElementById('status');
var progressElement = document.getElementById('progress');
if (m) {
text = m[1];
progressElement.value = parseInt(m[2])*100;
progressElement.max = parseInt(m[4])*100;
progressElement.hidden = false;
} else {
progressElement.value = null;
progressElement.max = null;
progressElement.hidden = true;
}
statusElement.innerHTML = text;
2021-10-22 22:27:58 +00:00
statusElement.hidden = text.length==0;
},
// preRun: [],
totalDependencies: 0,
monitorRunDependencies: function(left)
{ //progress is progress...
2015-08-07 17:49:49 +00:00
this.totalDependencies = Math.max(this.totalDependencies, left);
Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.');
2021-10-22 22:27:58 +00:00
},
// onRuntimeInitialized: function(){},
postRun:
[ //each of these are called after main was run. we should have our mainloop set up now
function()
{
if (Module["sched"] === undefined)
{ //our main function failed to set up the main loop. ie: main didn't get called. panic.
alert("Unable to initialise. You may need to restart your browser. If you get this often and inconsistently, consider using a 64bit browser instead.");
Module.setStatus("Initialisation Failure");
}
}
],
2015-08-07 17:49:49 +00:00
};
2021-10-22 22:27:58 +00:00
function begin()
{
if (Module.began)
return;
Module.began = true;
document.getElementById('dropzone').hidden = true;
document.getElementById('begin').hidden = true;
Module.setStatus('Downloading...');
2014-08-25 07:35:41 +00:00
2021-10-22 22:27:58 +00:00
// make a script. do it the hard way for the error.
var s = document.createElement('script');
// set it up
s.setAttribute('src',"ftewebgl.js");
s.setAttribute('type',"text/javascript");
s.setAttribute('charset',"utf-8");
s.addEventListener('error', function() {alert("Oh noes! we got an error!"); Module.setStatus("Unable to download engine javascript");}, false);
// add to DOM
document.head.appendChild(s);
}
2014-08-25 07:35:41 +00:00
2021-10-22 22:27:58 +00:00
//stuff to facilitate our drag+drop filesystem support
function fixupfilepath(fname, path)
{ //we just have a filename, try to guess where to put it.
if (path != "")
return path+fname; //already has a path. use it. this allows people to drag+drop gamedirs.
var ext = fname.substr(fname.lastIndexOf('.') + 1);
if (ext == 'fmf' || ext == 'kpf') //these are the only files that really make sense in the root.
return fname;
if (ext == 'bsp' || ext == 'map' || ext == 'lit' || ext == 'lux')
return "id1/maps/" + fname; //bsps get their own extra subdir
return "id1/" + fname; //probably a pak. maybe a cfg, no idea really.
}
function showfiles()
{ //print the pending file list in some pretty way
if (Module.began)
return;
Module.setStatus('');
document.getElementById('dropzone').hidden = false;
document.getElementById('begin').hidden = false;
var nt = "Drag gamedirs or individual package files here to make them available!< br / > Active Files:< br / > < pre > ";
var keys = Object.keys(Module.files);
for(var i = 0; i < keys.length ; i + + )
{
if (Module.files[keys[i]] instanceof ArrayBuffer)
{
var sz = Module.files[keys[i]].byteLength;
if (sz > 512*1024)
sz = (sz / (1024*1024)) + "mb";
else if (sz > 512)
sz = (sz / 1024) + "kb";
else
sz = (sz) + " bytes";
nt += " " + keys[i] + " ("+sz+")< br / > ";
}
else
nt += " " + keys[i] + "< br / > ";
}
nt += "< / pre > ("+keys.length+" files)";
document.getElementById('dropzone').innerHTML = nt;
}
function scanfiles(item,path)
{ //for directory drops
if (item.isFile)
{
item.file(function(f)
{
let n = fixupfilepath(f.name, path);
Module.files[n]=f.arrayBuffer(); //actually a promise...
Module.files[n].then(buf=>{Module.files[n]=buf;showfiles();}); //try and resolve it now.
});
}
else if (item.isDirectory)
{
// Get folder contents
var dirReader = item.createReader();
dirReader.readEntries(function(entries)
{
for (var i=0; i< entries.length ; i + + )
scanfiles(entries[i], path + item.name + "/");
});
}
}
function gotdrop(ev)
{ //user drag+dropped something.
ev.preventDefault();
for (var i = 0; i < ev.dataTransfer.items.length ; i + + )
if (ev.dataTransfer.items[i].webkitGetAsEntry)
{
var d = ev.dataTransfer.items[i].webkitGetAsEntry();
if (d)
scanfiles(d, "");
}
else if (ev.dataTransfer.items[i].kind === 'file')
{
var f = ev.dataTransfer.items[i].getAsFile();
var n = fixupfilepath(f.name);
Module.files[n]=f.arrayBuffer(); //actually a promise...
Module.files[n].then(buf=>{Module.files[n]=buf;showfiles();}); //try and resolve it now.
}
showfiles();
}
if (window.location.hash != "" || Object.keys(Module.files).length)
begin(); //if the url has a #foo.fmf then just begin instantly,
else
showfiles(); //otherwise show our lame file dropper and wait for the user to click 'go'.
2015-08-07 17:49:49 +00:00
< / script >
2014-08-25 07:35:41 +00:00
< / body >
2021-10-22 22:27:58 +00:00
< / html >