Chromium Code Reviews| Index: ports/quakespasm/quakespasm.js |
| diff --git a/ports/quakespasm/quakespasm.js b/ports/quakespasm/quakespasm.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..5c8490870fc719b82cdbcbdae209e87ae76895c5 |
| --- /dev/null |
| +++ b/ports/quakespasm/quakespasm.js |
| @@ -0,0 +1,138 @@ |
| +/* |
| + * Copyright (c) 2014 The Native Client Authors. All rights reserved. |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +var PAK_FILE = 'id1/pak0.pak'; |
| + |
| +function updateStatus(message) { |
| + document.getElementById('status').innerHTML += message + '<br />'; |
| +} |
| + |
| +/* |
| + * Creates and add to the DOM the NaCl embed tag which |
| + * in effect launches Quake. |
| + */ |
| +function runQuake(pwd) { |
| + var embed = document.createElement('object'); |
|
binji
2014/07/18 23:48:04
s/object/embed/
Sam Clegg
2014/07/19 00:59:49
We use object in naclterm.js .. and it seems that
binji
2014/07/21 17:45:48
yeah object w/ a data element is the old way and e
Sam Clegg
2014/07/21 18:05:27
Done. I figured out how to use the 'embed' elemen
|
| + embed.width = 800; |
| + embed.height = 600; |
| + embed.data = 'quakespasm.nmf'; |
| + embed.type = 'application/x-nacl'; |
| + if (pwd) { |
| + var param = document.createElement('param'); |
|
binji
2014/07/18 23:48:04
Use
embed.setAttribute('PWD', pwd);
instead?
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + param.name = 'PWD'; |
|
binji
2014/07/18 23:48:03
seems a bit weird that PWD changes the directory i
Sam Clegg
2014/07/19 00:59:49
PWD is what bash uses in its environment and its w
|
| + param.value = pwd; |
| + embed.appendChild(param); |
| + } |
| + document.getElementById('quake').appendChild(embed); |
| +} |
| + |
| +function extractZipFile(file, filesystem) { |
|
binji
2014/07/18 23:48:04
Yikes! I'd break this up into smaller functions pe
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + updateStatus('Extracting file: ' + file.name); |
| + zip.createReader(new zip.BlobReader(file), |
| + function(zipReader) { |
| + zipReader.getEntries(function(entries) { |
| + entries_written = 0; |
| + for (var i in entries) { |
| + var entry = entries[i]; |
| + if (entry.directory) { |
| + filesystem.root.getDirectory(entry.filename, { create : true }, |
| + function() { |
| + entries_written += 1; |
| + } |
| + ); |
| + continue; |
| + } else { |
| + filesystem.root.getFile(entry.filename, |
| + { create : true }, |
| + function(fileEntry) { |
| + var writer = new zip.FileWriter(fileEntry); |
| + entry.getData(writer, |
| + function() { |
| + entries_written += 1; |
| + if (entries_written === entries.length) { |
| + // Once we have extracted all the files then |
| + // launch the game. |
| + runQuake('/tmp'); |
|
binji
2014/07/18 23:48:04
probably a little more javascript-y to have a call
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + } |
| + }); |
| + }, |
| + function(error) { |
| + updateStatus('error creating temp file: ' + error); |
| + } |
| + ); |
| + } |
| + } |
| + }); |
| + }, |
| + function() { |
| + updateStatus('Error reading zip file'); |
| + } |
| + ) |
| +} |
| + |
| +function uploadDidChange(event) { |
| + navigator.webkitTemporaryStorage.requestQuota(3 * 1024 * 1024, |
| + function(bytes) { |
|
binji
2014/07/18 23:48:04
what if the quota isn't granted? I guess the user
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + window.webkitRequestFileSystem(window.TEMPORARAY, bytes, function(fs) { |
|
binji
2014/07/18 23:48:04
sp: TEMPORARY
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + var file = event.target.files[0]; |
| + extractZipFile(file, fs); |
| + }); |
| + } |
| + ); |
| +} |
| + |
| +function loadFromLocalStorage() { |
| + function loadFailure() { |
| + updateStatus('Quake data not found in local html5 filesystem.'); |
| + updateStatus('Please locate a quake level set (for example the ' |
| + + '<a href="http://www.libsdl.org/projects/quake/data/quakesw-1.0.6.zip">' |
| + + 'shareware levels</a>) and either extract them alongside the nmf file,' |
| + + ' or use the upload button below to unzip them in the local html5' |
| + + ' filesystem.'); |
| + // Create an html5 file input elemnt in so the user can upload the game |
| + // data as a zip file. |
| + document.getElementById('quake').innerHTML = |
| + '<input type="file" accept="application/zip" id="infile">'; |
| + document.getElementById('infile').addEventListener('change', |
| + uploadDidChange, |
| + false); |
| + } |
| + |
| + function loadSuccess() { |
| + updateStatus('Found pak file in local storage. Launching quake.'); |
| + runQuake('/tmp'); |
| + } |
| + |
| + window.webkitRequestFileSystem( |
| + window.TEMPORARAY, 3 * 1024 * 1024, |
|
binji
2014/07/18 23:48:04
TEMPORARY
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + function(fs) { |
| + fs.root.getFile(PAK_FILE, {}, loadSuccess, loadFailure); |
| + } |
| + ); |
| +} |
| + |
| +function onLoad() { |
| + updateStatus('Searching for Quake data (' + PAK_FILE + ')'); |
| + var req = new XMLHttpRequest(); |
| + req.onreadystatechange = function() { |
|
binji
2014/07/18 23:48:04
I prefer using onload/onerror. onreadystatechange
Sam Clegg
2014/07/19 00:59:49
Done.
|
| + if (req.readyState === 4) { |
| + if (req.status === 200) { |
| + updateStatus('Found ' + PAK_FILE + '. Launching quake.'); |
| + runQuake(); |
| + } else { |
| + // Failed to find PAK_FILE on webserver, try local storage |
| + updateStatus('Quake data not found alongside executable.'); |
| + loadFromLocalStorage(); |
| + } |
| + } |
| + }; |
| + req.open('GET', PAK_FILE); |
| + req.send(null); |
| +} |
| + |
| +window.onload = function() { |
| + onLoad(); |
| +}; |