started on Share Embed Link; removed emubevel class; load support scripts at runtime

This commit is contained in:
Steven Hugg 2018-08-23 23:58:35 -04:00
parent 1f32eee70c
commit cb22adeb62
13 changed files with 12846 additions and 51 deletions

View File

@ -215,21 +215,17 @@ div.emulator {
margin-top: 20px auto 0;
height:100%;
}
.emubevel {
width:100%;
height:100%;
padding:5%;
background:#555;
}
/* has to be here b/c renders differently after first load if in inline style */
.emuvideo {
border-radius:20px;
border: 4px solid #222;
padding: 30px;
margin-top: 10px;
margin-bottom: 10px;
background: #000;
outline-color: #666;
width: 100%;
padding: 30px;
background: #000;
margin-top:40px;
margin-left:7.5%;
margin-right:7.5%;
width: 85%;
}
canvas.pixelated {
image-rendering: optimizeSpeed; /* Older versions of FF */

View File

@ -35,7 +35,6 @@ TODO:
- update Javatari version? (and others?)
- unify versioning
- more UI tests
- base-36 encoding for LZG
- disassembler for uploaded ROMs
- show tool-specific (readonly) include files
- verilog debugging/reloading makes it slow

176
embed.html Normal file
View File

@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>8bitworkshop IDE</title>
<style type="text/css" media="screen">
#emulator {
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
background-color:#555;
display: flex;
align-items: center;
justify-content: center;
}
.emuvideo {
height:80%;
border-radius:20px;
border: 4px solid #222;
outline-color: #666;
padding: 30px;
background: #000;
}
</style>
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
if (window.location.host.endsWith('8bitworkshop.com')) {
ga('create', 'UA-54497476-9', 'auto');
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
</head>
<body>
<div id="emulator">
<div id="javatari-div" style="margin:10px; display:none">
<div id="javatari-screen" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
<div id="javatari-console-panel" style="margin: 0 auto; box-shadow: 2px 2px 10px rgb(60, 60, 60);"></div>
</div>
</div>
<script src="jquery/jquery-2.2.3.min.js"></script>
<script src="javatari.js/release/javatari/javatari.js"></script>
<script src="src/cpu/z80fast.js"></script>
<script src="jsnes/jsnes.min.js"></script>
<!--<script src="src/cpu/6809.js"></script>-->
<script>
var exports = {};
function require(modname) {
if (modname == 'jquery') return $;
else if (modname.startsWith('.')) return exports;
else { console.log("Unknown require()", modname); return exports; }
}
</script>
<script src="tss/js/tss/PsgDeviceChannel.js"></script>
<script src="tss/js/tss/MasterChannel.js"></script>
<script src="tss/js/tss/AudioLooper.js"></script>
<script src="tss/js/Log.js"></script>
<script src="gen/util.js"></script>
<script src="gen/store.js"></script>
<script src="src/vlist.js"></script>
<script src="gen/emu.js"></script>
<script src="gen/baseplatform.js"></script>
<script src="gen/audio.js"></script>
<script src="gen/recorder.js"></script>
<script src="lib/liblzg.js"></script>
<script>
window.Javatari.AUTO_START = false;
var PLATFORMS = exports.PLATFORMS;
var platform, platform_id;
var qs = (function (a) {
if (!a || a.length == 0)
return {};
var b = {};
for (var i = 0; i < a.length; ++i) {
var p = a[i].split('=', 2);
if (p.length == 1)
b[p[0]] = "";
else
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(window.location.search.substr(1).split('&'));
// catch errors
function installErrorHandler() {
if (typeof window.onerror == "object") {
window.onerror = function (msgevent, url, line, col, error) {
ga('send', 'exception', {
'exDescription': msgevent + " " + url + " " + " " + line + ":" + col + ", " + error,
'exFatal': true
});
//alert(msgevent+"");
};
}
}
function uninstallErrorHandler() {
window.onerror = null;
}
function addPageFocusHandlers() {
var hidden = false;
document.addEventListener("visibilitychange", function() {
if (document.visibilityState == 'hidden' && platform.isRunning()) {
platform.pause();
hidden = true;
} else if (document.visibilityState == 'visible' && hidden) {
platform.resume();
hidden = false;
}
});
$(window).on("focus", function() {
if (hidden) {
platform.resume();
hidden = false;
}
});
$(window).on("blur", function() {
if (platform.isRunning()) {
platform.pause();
hidden = true;
}
});
}
function startPlatform() {
if (!PLATFORMS[platform_id]) throw Error("Invalid platform '" + platform_id + "'.");
platform = new PLATFORMS[platform_id]($("#emulator")[0]);
platform.start();
var title = qs['n'] || 'Game';
var lzgrom = stringToByteArray(atob(qs['r']));
var rom = new lzgmini().decode(lzgrom);
console.log(rom.length + ' bytes');
platform.loadROM(title, rom);
platform.resume();
return true;
}
function loadScript(scriptfn, onload) {
var script = document.createElement('script');
script.onload = onload;
script.src = scriptfn;
document.getElementsByTagName('head')[0].appendChild(script);
}
// start
function startEmbed() {
installErrorHandler();
// add default platform?
platform_id = qs['p'];
if (!platform_id) throw('No platform variable!');
var scriptfn = 'gen/platform/' + platform_id.split(/[.-]/)[0] + '.js';
loadScript(scriptfn, () => {
console.log("loaded platform", platform_id);
startPlatform();
});
}
startEmbed();
</script>
</body>
</html>

View File

@ -48,11 +48,11 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<li><a class="dropdown-item" href="#" id="item_new_file">New Project...</a></li>
<li><a class="dropdown-item" href="#" id="item_upload_file">Upload File...</a></li>
<!--<li><a class="dropdown-item" href="#" id="item_share_file">Share File as GitHub Gist...</a></li>-->
<li><a class="dropdown-item" href="#" id="item_reset_file">Revert to Original...</a></li>
<li><a class="dropdown-item" href="#" id="item_download_file">Download Source File</a></li>
<li><a class="dropdown-item" href="#" id="item_download_rom">Download ROM Image</a></li>
<li><a class="dropdown-item" href="#" id="item_record_video">Record Video...</a></li>
<li><a class="dropdown-item" href="#" id="item_share_file">Share Playable Link...</a></li>
<li class="dropdown dropdown-submenu">
<a tabindex="-1" href="#">Debug</a>
<ul class="dropdown-menu">
@ -221,6 +221,27 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
</div>
</div>
</div>
<div id="embedLinkModal" class="modal fade">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Share Playable Link</h3>
</div>
<div class="modal-body">
<p>Here's a direct link to a playable version of your game:</p>
<textarea rows="4" cols="80" id="embedLinkTextarea" class="cliptext"></textarea>
<button type="button" class="btn btn-primary" data-clipboard-target="#embedLinkTextarea">Copy Direct Link</button>
<p>You can also embed it into an IFRAME:</p>
<textarea rows="4" cols="80" id="embedIframeTextarea" class="cliptext"></textarea>
<button type="button" class="btn btn-primary" data-clipboard-target="#embedIframeTextarea">Copy IFRAME Tag</button>
</div>
<div class="modal-footer">
Choose one (or none) then
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script src="jquery/jquery-2.2.3.min.js"></script>
@ -256,8 +277,6 @@ if (window.location.host.endsWith('8bitworkshop.com')) {
<script src="local/atarivec/gravitar/gravitar.js"></script>
-->
<script src="FileSaver.js/FileSaver.min.js"></script>
<script src="octokat.js/dist/octokat.js"></script>
<script src="gif.js/dist/gif.js"></script>
<script src="localForage/dist/localforage.nopromises.js"></script>
<script>

7
lib/clipboard.min.js vendored Normal file

File diff suppressed because one or more lines are too long

12403
lib/liblzg.js Normal file

File diff suppressed because it is too large Load Diff

135
package-lock.json generated
View File

@ -52,6 +52,18 @@
"json-schema-traverse": "0.3.1"
}
},
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
"dev": true
},
"array-equal": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
@ -119,6 +131,12 @@
"tweetnacl": "0.14.5"
}
},
"bluebird": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.0.5.tgz",
"integrity": "sha1-L/nQfJs+2ynW0oD+B1KDZefs05I=",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -147,6 +165,30 @@
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
"dev": true
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
"ansi-styles": "2.2.1",
"escape-string-regexp": "1.0.5",
"has-ansi": "2.0.0",
"strip-ansi": "3.0.1",
"supports-color": "2.0.0"
}
},
"clipboard": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.1.tgz",
"integrity": "sha512-7yhQBmtN+uYZmfRjjVjKa0dZdWuabzpSKGtyQZN+9C8xlC788SSJjOHWh7tzurfwTqTD5UDYAhIv5fRJg3sHjQ==",
"dev": true,
"requires": {
"good-listener": "1.2.2",
"select": "1.1.2",
"tiny-emitter": "2.0.2"
}
},
"co": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@ -162,6 +204,15 @@
"delayed-stream": "1.0.0"
}
},
"commander": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz",
"integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=",
"dev": true,
"requires": {
"graceful-readlink": "1.0.1"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
@ -221,6 +272,12 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
"delegate": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==",
"dev": true
},
"domexception": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
@ -308,6 +365,15 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"filepath": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/filepath/-/filepath-1.1.0.tgz",
"integrity": "sha1-173JSJbZdS+o+iN+J16emOYwmO0=",
"dev": true,
"requires": {
"bluebird": "3.0.5"
}
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
@ -340,6 +406,21 @@
"assert-plus": "1.0.0"
}
},
"good-listener": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"dev": true,
"requires": {
"delegate": "3.2.0"
}
},
"graceful-readlink": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
"integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=",
"dev": true
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
@ -356,6 +437,15 @@
"har-schema": "2.0.0"
}
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
@ -517,6 +607,18 @@
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
"dev": true
},
"lzg": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lzg/-/lzg-1.0.0.tgz",
"integrity": "sha1-S9MHpk4FbGTWBSqRt+rlwmqopRY=",
"dev": true,
"requires": {
"chalk": "1.1.3",
"commander": "2.9.0",
"filepath": "1.1.0",
"pkginfo": "0.4.1"
}
},
"mime-db": {
"version": "1.35.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
@ -698,6 +800,12 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
"dev": true
},
"pkginfo": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
"integrity": "sha1-tUGO8EOd5UJfxJlQQtztFPsqhP8=",
"dev": true
},
"pn": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
@ -794,6 +902,12 @@
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
"dev": true
},
"select": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=",
"dev": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -824,12 +938,33 @@
"integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
"dev": true
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"dev": true,
"requires": {
"ansi-regex": "2.1.1"
}
},
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
},
"symbol-tree": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
"integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=",
"dev": true
},
"tiny-emitter": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
"integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==",
"dev": true
},
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",

View File

@ -8,8 +8,10 @@
"@types/jquery": "^2.x",
"atob": "^2.1.2",
"btoa": "^1.2.1",
"clipboard": "^2.0.1",
"heapdump": "^0.3.9",
"jsdom": "^12.0.0",
"lzg": "^1.0.0",
"mocha": "^5.2.0",
"typescript": "^2.9.2",
"wavedrom-cli": "^0.5.0"

View File

@ -32,18 +32,12 @@ export function setNoiseSeed(x : number) {
type KeyboardCallback = (which:number, charCode:number, flags:number) => void;
function __createCanvas(mainElement:HTMLElement, width:number, height:number) : HTMLElement {
// TODO
var fsElement = document.createElement('div');
fsElement.classList.add("emubevel");
var canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
canvas.classList.add("emuvideo");
canvas.tabIndex = -1; // Make it focusable
fsElement.appendChild(canvas);
mainElement.appendChild(fsElement);
mainElement.appendChild(canvas);
return canvas;
}

View File

@ -61,7 +61,7 @@ const _Apple2Platform = function(mainElement) {
cpu = new jt.M6502();
ram = new RAM(0x13000); // 64K + 16K LC RAM - 4K hardware
// ROM
var rom = new lzgmini().decode(APPLEIIGO_LZG).slice(0,0x3000);
var rom = new lzgmini().decode(APPLEIIGO_LZG);
ram.mem.set(rom, 0xd000);
ram.mem[0xbf00] = 0x4c; // fake DOS detect for C
ram.mem[0xbf6f] = 0x01; // fake DOS detect for C

View File

@ -11,11 +11,13 @@ import { Platform, Preset } from "./baseplatform";
import { PLATFORMS } from "./emu";
import * as Views from "./views";
import { createNewPersistentStore } from "./store";
import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap } from "./util";
import { getFilenameForPath, getFilenamePrefix, highlightDifferences, invertMap, byteArrayToString, compressLZG } from "./util";
import { StateRecorderImpl } from "./recorder";
// external libs (TODO)
declare var Octokat, ga, Tour, GIF, saveAs;
declare var ga, Tour, GIF, saveAs;
// in index.html
declare var exports;
// make sure VCS doesn't start
if (window['Javatari']) window['Javatari'].AUTO_START = false;
@ -288,14 +290,15 @@ function getCurrentEditorFilename() : string {
return getFilenameForPath(projectWindows.getActiveID());
}
function _shareFile(e) {
function _shareFileAsGist(e) {
loadScript("octokat.js/dist/octokat.js", () => {
if (current_output == null) { // TODO
alert("Please fix errors before sharing.");
return true;
}
var text = projectWindows.getCurrentText();
if (!text) return false;
var github = new Octokat();
var github = new exports['Octokat']();
var files = {};
files[getCurrentEditorFilename()] = {"content": text};
var gistdata = {
@ -309,6 +312,40 @@ function _shareFile(e) {
}).fail(function(err) {
alert("Error sharing file: " + err.message);
});
});
}
function _shareEmbedLink(e) {
if (current_output == null) { // TODO
alert("Please fix errors before sharing.");
return true;
}
loadScript('lib/clipboard.min.js', () => {
var ClipboardJS = exports['ClipboardJS'];
new ClipboardJS(".btn");
});
loadScript('lib/liblzg.js', () => {
// TODO: Module is bad var name
var lzgrom = compressLZG( window['Module'], current_output );
window['Module'] = null; // so we load it again next time
var lzgb64 = btoa(byteArrayToString(lzgrom));
var embed = {
p: platform_id,
//n: main_file_id,
r: lzgb64
};
var linkqs = $.param(embed);
console.log(linkqs);
var loc = window.location;
var prefix = loc.pathname.replace('index.html','');
var protocol = (loc.host == '8bitworkshop.com') ? 'https:' : loc.protocol;
var fulllink = protocol+'//'+loc.host+prefix+'embed.html?' + linkqs;
var iframelink = '<iframe width=640 height=600 src="' + fulllink + '">';
$("#embedLinkTextarea").text(fulllink);
$("#embedIframeTextarea").text(iframelink);
$("#embedLinkModal").modal('show');
//document.execCommand("copy");
});
return true;
}
@ -595,6 +632,7 @@ function updateDebugWindows() {
}
function _recordVideo() {
loadScript("gif.js/dist/gif.js", () => {
var canvas = $("#emulator").find("canvas")[0];
if (!canvas) {
alert("Could not find canvas element to record video!");
@ -607,6 +645,7 @@ function _recordVideo() {
else if (canvas.style.transform.indexOf("rotate(90deg)") >= 0)
rotate = 1;
}
// TODO: recording indicator?
var gif = new GIF({
workerScript: 'gif.js/dist/gif.worker.js',
workers: 4,
@ -637,6 +676,7 @@ function _recordVideo() {
}
};
f();
});
}
function setFrameRateUI(fps:number) {
@ -751,7 +791,7 @@ function setupDebugControls(){
$(".dropdown-menu").collapse({toggle: false});
$("#item_new_file").click(_createNewFile);
$("#item_upload_file").click(_uploadNewFile);
$("#item_share_file").click(_shareFile);
$("#item_share_file").click(_shareEmbedLink);
$("#item_reset_file").click(_revertFile);
if (platform.runEval)
$("#item_debug_expr").click(_breakExpression).show();
@ -968,7 +1008,8 @@ function startPlatform() {
}
function loadSharedFile(sharekey : string) {
var github = new Octokat();
loadScript("octokat.js/dist/octokat.js", () => {
var github = new exports['Octokat']();
var gist = github.gists(sharekey);
gist.fetch().done(function(val) {
var filename;
@ -987,7 +1028,7 @@ function loadSharedFile(sharekey : string) {
}).fail(function(err) {
alert("Error loading share file: " + err.message);
});
return true;
});
}
function loadScript(scriptfn, onload) {

View File

@ -127,6 +127,9 @@ export function lzgmini() {
{
return null;
}
// what's the length?
var uncomplen = data[6] | (data[5]<<8) | (data[4]<<16) | (data[3]<<24);
// Calculate & check the checksum
var checksum = ((data[11] & 0xff) << 24) |
@ -138,6 +141,7 @@ export function lzgmini() {
return null;
}
var dst = new Array();
// Check which method to use
var method = data[15] & 0xff;
if (method == LZG_METHOD_LZG1)
@ -150,7 +154,6 @@ export function lzgmini() {
// Main decompression loop
var symbol, b, b2, b3, len, offset;
var dst = new Array();
var dstlen = 0;
var k = LZG_HEADER_SIZE + 4;
var datalen = data.length;
@ -211,28 +214,26 @@ export function lzgmini() {
}
}
// Store the decompressed data in the lzgmini object for later retrieval
outdata = dst;
return outdata;
}
else if (method == LZG_METHOD_COPY)
{
// Plain copy
var dst = new Array();
var dstlen = 0;
var datalen = data.length;
for (var i = LZG_HEADER_SIZE; i < datalen; i++)
{
dst[dstlen++] = data[i] & 0xff;
}
outdata = dst;
return outdata;
}
else
{
// Unknown method
return null;
}
// Store the decompressed data in the lzgmini object for later retrieval
if (dst.length < uncomplen) return null; // data too short
outdata = dst.slice(0, uncomplen);
return outdata;
}
// Get the decoded byte array
@ -242,19 +243,8 @@ export function lzgmini() {
}
// Get the decoded string from a Latin 1 (or ASCII) encoded array
this.getStringLatin1 = function():string
{
var str = "";
if (outdata != null)
{
var charLUT = new Array();
for (var i = 0; i < 256; ++i)
charLUT[i] = String.fromCharCode(i);
var outlen = outdata.length;
for (var i = 0; i < outlen; i++)
str += charLUT[outdata[i]];
}
return str;
this.getStringLatin1 = function():string {
return byteArrayToString(outdata);
}
// Get the decoded string from an UTF-8 encoded array
@ -301,9 +291,42 @@ export function stringToByteArray(s:string) : Uint8Array {
return a;
}
export function byteArrayToString(outdata : number[] | Uint8Array) : string {
var str = "";
if (outdata != null) {
var charLUT = new Array();
for (var i = 0; i < 256; ++i)
charLUT[i] = String.fromCharCode(i);
var outlen = outdata.length;
for (var i = 0; i < outlen; i++)
str += charLUT[outdata[i]];
}
return str;
}
export function removeBOM(s:string) {
if (s.charCodeAt(0) === 0xFEFF) {
s = s.substr(1);
}
return s;
}
// need to load liblzg.js first
export function compressLZG(em_module, inBuffer:number[], levelArg?:boolean) : Uint8Array {
var level = levelArg || 9;
var inLen = inBuffer.length;
var inPtr = em_module._malloc(inLen + 1);
for (var i = 0; i < inLen; i++) {
em_module.setValue(inPtr + i, inBuffer[i], 'i8');
}
var maxEncSize = em_module._LZG_MaxEncodedSize(inLen);
var outPtr = em_module._malloc(maxEncSize + 1);
var compLen = em_module.ccall('compress_lzg', 'number', ['number', 'number', 'number', 'number', 'number'], [level, inPtr, inLen, maxEncSize, outPtr]);
em_module._free(inPtr);
var outBuffer = new Uint8Array(compLen);
for (var i = 0; i < compLen; i++) {
outBuffer[i] = em_module.getValue(outPtr + i, 'i8');
}
em_module._free(outPtr);
return outBuffer;
}

View File

@ -107,6 +107,6 @@ var NES_CONIO_ROM_LZG = [
describe('LZG', function() {
it('Should decode LZG', function() {
var rom = new Uint8Array(new util.lzgmini().decode(NES_CONIO_ROM_LZG));
assert.equal(40977, rom.length);
assert.equal(40976, rom.length);
});
});