Add cue file generator

This commit is contained in:
Ethan O'Brien 2023-07-06 11:33:12 -05:00
parent acc0052192
commit ae6b00a3fe
3 changed files with 100 additions and 39 deletions

View file

@ -137,6 +137,49 @@ class EJS_GameManager {
} }
this.functions.simulateInput(player, index, value); this.functions.simulateInput(player, index, value);
} }
createCueFile(fileNames) {
try {
fileNames = fileNames.sort((a, b) => {
return (parseInt(a.charAt()[0]) > parseInt(b.charAt()[0])) ? 1 : -1;
})
fileNames = fileNames.filter((item) => {
return ["toc", "ccd", "exe", "pbp", "chd", "img", "bin"].includes(item.split(".").pop().toLowerCase());
})
} catch(e) {
if (fileNames.length > 1) {
console.warn("Could not auto-create cue file(s).");
return null;
}
}
for (let i=0; i<fileNames.length; i++) {
if (fileNames[i].split(".").pop().toLowerCase() === "ccd") {
console.warn("Did not auto-create cue file(s). Found a ccd.");
return null;
}
}
if (fileNames.length === 0) {
console.warn("Could not auto-create cue file(s).");
return null;
}
console.log(fileNames);
let baseFileName = fileNames[0].split("/").pop();
if (baseFileName.includes(".")) {
baseFileName = baseFileName.substring(0, baseFileName.length - baseFileName.split(".").pop().length - 1);
console.log(baseFileName);
}
for (let i=0; i<fileNames.length; i++) {
const contents = " FILE \""+fileNames[i]+"\" BINARY\n TRACK 01 MODE1/2352\n INDEX 01 00:00:00";
FS.writeFile("/"+baseFileName+"-"+i+".cue", contents);
}
if (fileNames.length > 1) {
let contents = "";
for (let i=0; i<fileNames.length; i++) {
contents += "/"+baseFileName+"-"+i+".cue\n";
}
FS.writeFile("/"+baseFileName+".m3u", contents);
}
return (fileNames.length === 1) ? baseFileName+"-0.cue" : baseFileName+".m3u";
}
toggleMainLoop(playing) { toggleMainLoop(playing) {
this.functions.toggleMainLoop(playing); this.functions.toggleMainLoop(playing);
} }

View file

@ -1,20 +1,5 @@
class EmulatorJS { class EmulatorJS {
version = { version = 1; //All versions for the core
a5200: 1,
beetle_vb: 1,
desmume2015: 1,
fbalpha2012_cps1: 1,
fbalpha2012_cps2: 1,
fceumm: 1,
gambatte: 1,
mame2003: 1,
mednafen_psx_hw: 1,
melonds: 1,
mgba: 1,
mupen64plus_next: 1,
nestopia: 1,
snes9x: 1
}
getCore(generic) { getCore(generic) {
const core = this.config.system; const core = this.config.system;
//todo: sega32x, TurboGrafs-16 (pce), Wanderswan (ws), ngp, msx //todo: sega32x, TurboGrafs-16 (pce), Wanderswan (ws), ngp, msx
@ -422,12 +407,13 @@ class EmulatorJS {
} }
this.downloadFile("compression/libunrar.js", (res) => { this.downloadFile("compression/libunrar.js", (res) => {
if (res === -1) { this.downloadFile("compression/libunrar.js.mem", (res2) => {
if (res === -1 || res2 === -1) {
this.textElem.innerText = "Error"; this.textElem.innerText = "Error";
this.textElem.style.color = "red"; this.textElem.style.color = "red";
return; return;
} }
const path = origin + this.config.dataPath + 'compression/libunrar.js.mem'; const path = URL.createObjectURL(new Blob([res2]));
let data = '\nlet dataToPass = [];\nModule = {\n monitorRunDependencies: function(left) {\n if (left == 0) {\n setTimeout(function() {\n unrar(dataToPass, null);\n }, 100);\n }\n },\n onRuntimeInitialized: function() {\n },\n locateFile: function(file) {\n return \''+path+'\';\n }\n};\n'+res.data+'\nlet unrar = function(data, password) {\n let cb = function(fileName, fileSize, progress) {\n postMessage({"t":4,"current":progress,"total":fileSize, "name": fileName});\n };\n\n let rarContent = readRARContent(data.map(function(d) {\n return {\n name: d.name,\n content: new Uint8Array(d.content)\n }\n }), password, cb)\n let rec = function(entry) {\n if (entry.type === \'file\') {\n postMessage({"t":2,"file":entry.fullFileName,"size":entry.fileSize,"data":entry.fileContent});\n } else if (entry.type === \'dir\') {\n Object.keys(entry.ls).forEach(function(k) {\n rec(entry.ls[k]);\n })\n } else {\n throw "Unknown type";\n }\n }\n rec(rarContent);\n postMessage({"t":1});\n return rarContent;\n};\nonmessage = function(data) {\n dataToPass.push({name: \'test.rar\', content: data.data});\n};\n '; let data = '\nlet dataToPass = [];\nModule = {\n monitorRunDependencies: function(left) {\n if (left == 0) {\n setTimeout(function() {\n unrar(dataToPass, null);\n }, 100);\n }\n },\n onRuntimeInitialized: function() {\n },\n locateFile: function(file) {\n return \''+path+'\';\n }\n};\n'+res.data+'\nlet unrar = function(data, password) {\n let cb = function(fileName, fileSize, progress) {\n postMessage({"t":4,"current":progress,"total":fileSize, "name": fileName});\n };\n\n let rarContent = readRARContent(data.map(function(d) {\n return {\n name: d.name,\n content: new Uint8Array(d.content)\n }\n }), password, cb)\n let rec = function(entry) {\n if (entry.type === \'file\') {\n postMessage({"t":2,"file":entry.fullFileName,"size":entry.fileSize,"data":entry.fileContent});\n } else if (entry.type === \'dir\') {\n Object.keys(entry.ls).forEach(function(k) {\n rec(entry.ls[k]);\n })\n } else {\n throw "Unknown type";\n }\n }\n rec(rarContent);\n postMessage({"t":1});\n return rarContent;\n};\nonmessage = function(data) {\n dataToPass.push({name: \'test.rar\', content: data.data});\n};\n ';
const blob = new Blob([data], { const blob = new Blob([data], {
'type': 'application/javascript' 'type': 'application/javascript'
@ -436,6 +422,7 @@ class EmulatorJS {
const worker = new Worker(url); const worker = new Worker(url);
worker.onmessage = onMessage; worker.onmessage = onMessage;
worker.postMessage(file); worker.postMessage(file);
}, null, false, {responseType: "text", method: "GET"})
}, null, false, {responseType: "text", method: "GET"}); }, null, false, {responseType: "text", method: "GET"});
}) })
@ -500,7 +487,7 @@ class EmulatorJS {
}); });
} }
this.storage.core.get(this.getCore()+'-wasm.data').then((result) => { this.storage.core.get(this.getCore()+'-wasm.data').then((result) => {
if (result && result.version === this.version[this.getCore()] && !this.debug) { if (result && result.version === this.version && !this.debug) {
gotCore(result.data); gotCore(result.data);
return; return;
} }
@ -512,7 +499,7 @@ class EmulatorJS {
} }
gotCore(res.data); gotCore(res.data);
this.storage.core.put(this.getCore()+'-wasm.data', { this.storage.core.put(this.getCore()+'-wasm.data', {
version: this.version[this.getCore()], version: this.version,
data: res.data data: res.data
}); });
}, (progress) => { }, (progress) => {
@ -590,8 +577,8 @@ class EmulatorJS {
break; break;
} }
if (k.endsWith('/')) continue; if (k.endsWith('/')) continue;
console.log(k.split('/').pop()); let folder = this.fileName.substring(0, this.fileName.length - this.fileName.split("/").pop().length);
FS.writeFile(k.split('/').pop(), data[k]); FS.writeFile(folder + k.split('/').pop(), data[k]);
} }
this.downloadStartState(); this.downloadStartState();
}) })
@ -634,10 +621,25 @@ class EmulatorJS {
return; return;
} }
this.checkCompression(new Uint8Array(data), this.localization("Decompress Game Data")).then((data) => { this.checkCompression(new Uint8Array(data), this.localization("Decompress Game Data")).then((data) => {
const fileNames = (() => {
let rv = [];
for (const k in data) rv.push(k);
return rv;
})();
let execFile = null;
if (this.getCore(true) === "psx") {
execFile = this.gameManager.createCueFile(fileNames);
}
console.log(data);
for (const k in data) { for (const k in data) {
if (k === "!!notCompressedData") { if (k === "!!notCompressedData") {
this.fileName = this.config.gameUrl.startsWith("blob:") ? this.config.gameName || "game" : this.config.gameUrl.split('/').pop().split("#")[0].split("?")[0]; const fileName = this.config.gameUrl.startsWith("blob:") ? this.config.gameName || "game" : this.config.gameUrl.split('/').pop().split("#")[0].split("?")[0];
FS.writeFile(this.fileName, data[k]); if (this.getCore(true) === "psx" && execFile !== null) {
this.fileName = execFile;
} else {
this.fileName = fileName;
}
FS.writeFile(fileName, data[k]);
break; break;
} }
if (k.endsWith('/')) { if (k.endsWith('/')) {
@ -646,11 +648,25 @@ class EmulatorJS {
} }
if (!this.fileName || (this.extensions[this.getCore()].includes(k.split(".").pop()) && if (!this.fileName || (this.extensions[this.getCore()].includes(k.split(".").pop()) &&
//always prefer m3u files for psx cores //always prefer m3u files for psx cores
!(this.getCore(true) === "psx" && this.fileName.split(".").pop() === "m3u"))) { !(this.getCore(true) === "psx" && ["m3u", "ccd"].includes(this.fileName.split(".").pop())))) {
this.fileName = k; this.fileName = k;
} }
console.log(k); if (k.includes("/")) {
FS.writeFile(k, data[k]); const paths = k.split("/");
let cp = "";
for (let i=0; i<paths.length-1; i++) {
if (paths[i] === "") continue;
cp += "/"+paths[i];
if (!FS.analyzePath(cp).exists) {
FS.mkdir(cp);
}
}
}
if (this.getCore(true) === "psx" && execFile !== null && ["m3u", "cue"].includes(k.split(".").pop().toLowerCase())) continue;
FS.writeFile("/"+k, data[k]);
}
if (this.getCore(true) === "psx" && execFile !== null) {
this.fileName = execFile;
} }
this.downloadBios(); this.downloadBios();
}); });

View file

@ -168,6 +168,8 @@
window.EJS_core = core window.EJS_core = core
window.EJS_pathtodata = "data/" window.EJS_pathtodata = "data/"
window.EJS_startOnLoaded = true; window.EJS_startOnLoaded = true;
window.EJS_DEBUG_XX = true;
EJS_biosUrl = 'roms/bios.zip';
if (window.location.hostname === "demo.emulatorjs.org") { if (window.location.hostname === "demo.emulatorjs.org") {
window.EJS_AdUrl = "https://ads.emulatorjs.org/"; window.EJS_AdUrl = "https://ads.emulatorjs.org/";