From d68e2f913a37e91d68255eee11b58876c170c25b Mon Sep 17 00:00:00 2001 From: yellows111 Date: Thu, 12 Oct 2023 10:51:46 +0100 Subject: [PATCH] in theory this works, in practice, i forgot to have a test file on hand --- icon.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ index.js | 4 ++++ input.htm | 48 ++++++++++++++++++++++++++++++++++-------------- 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/icon.js b/icon.js index 5e022ed..eba4ca7 100644 --- a/icon.js +++ b/icon.js @@ -1,6 +1,7 @@ //todo: Make this a module/mjs file. C6 compatibility can stay, if needed. ICONJS_DEBUG = false; ICONJS_STRICT = true; +ICONJS_VERSION = "0.3.3"; function setDebug(value) { ICONJS_DEBUG = !!value; @@ -269,6 +270,52 @@ function readEmsPsuFile(input){ return fsOut; } +function readPsvFile(input){ + const view = new DataView(input); + const u32le = function(i){return view.getUint32(i, 1)}; + //!pattern psv_file.hexpat + const magic = u32le(0); + if (magic !== 0x50535600) { + throw `Not a PS3 export (PSV) file (was ${magic}, expected ${0x50535600})`; + } + //:skip 4 + //:skip 20 // key seed, console ignores this + //:skip 20 // sha1 hmac digest, useful for... something + //:skip 8 + const type1 = u32le(52); + const type2 = u32le(56); + if(type1 !== 0x2c && type2 !== 2) { + throw `Not parsing, this is not a PS2 save export (was ${type1}:${type2}, expected 44:2)`; + } + const displayedSize = u32le(60); + const ps2dOffset = u32le(64); + const ps2dSize = u32le(68); // don't know why this is included if its always 964 + const nModelOffset = u32le(72); + const nModelSize = u32le(76); + const cModelOffset = u32le(80); + const cModelSize = u32le(84); + const dModelOffset = u32le(88); + const dModelSize = u32le(92); + const numberOfFiles = u32le(96); // in-case this library changes stance on other files + const rootDirectoryData = input.slice(100, 158); + let offset = 158; + let fileData = new Array(); + for (let index = 0; index < numberOfFiles; index++) { + fileData.push(input.slice(offset,offset+0x3c)); + offset += 0x3c; + }; + //then file data after this but we already have pointers to the files we care about + const icons = { + n: input.slice(nModelOffset, nModelOffset+nModelSize), + c: input.slice(cModelOffset, cModelOffset+cModelSize), + d: input.slice(dModelOffset, dModelOffset+dModelSize), + } + if (ICONJS_DEBUG) { + console.log({magic, type1, type2, displayedSize, ps2dOffset, ps2dSize, nModelOffset, nModelSize, cModelOffset, cModelSize, dModelOffset, dModelSize, numberOfFiles, rootDirectoryData, fileData}) + } + return {icons, "icon.sys": input.slice(ps2dOffset, ps2dOffset+ps2dSize)}; +} + if(typeof module !== "undefined") { // for C6JS module.exports = {readIconFile, readPS2D, readEmsPsuFile, setDebug, setStrictness}; diff --git a/index.js b/index.js index bb9ab51..5c7af50 100644 --- a/index.js +++ b/index.js @@ -21,6 +21,10 @@ if(processObj.argv[2] === "psu") { output[file] = iconjs.readIconFile(parsed[parsed.rootDirectory][PS2D.filenames[file]].data); }); console.log(output); +} else if(processObj.argv[2] === "psv") { + let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "file.psu"); + const parsed = iconjs.readPsvFile(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength)); + console.log(parsed); } else { let inputFile = filesystem.readFileSync(processObj.argv[2] ? processObj.argv[2] : "icon.sys"); const metadata = iconjs.readPS2D(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength)); diff --git a/input.htm b/input.htm index b71a626..2da4977 100644 --- a/input.htm +++ b/input.htm @@ -59,9 +59,12 @@

- +
+ + +

Date created: --:--:-- --/--/---- UTC+09:00
@@ -99,6 +102,15 @@ glContext.drawArrays(glContext.TRIANGLE_STRIP, 0, 4); } } + function resetDisplay() { + document.getElementById("title1").textContent = "\uff0d"; + document.getElementById("title2").textContent = "\uff0d"; + document.getElementById("iconn").textContent = "?"; + document.getElementById("iconc").textContent = "?"; + document.getElementById("icond").textContent = "?"; + document.getElementById("dateCreated").textContent = "--:--:-- --/--/----"; + document.getElementById("dateModified").textContent = "--:--:-- --/--/----"; + } document.getElementById("strictnessOption").onchange = function(e) { setStrictness(e.target.checked); if(!!filebox.files.length) {filebox.onchange();} @@ -107,11 +119,7 @@ } filebox = document.getElementById("input"); filebox.onchange = function(e) { - document.getElementById("title1").textContent = "\uff0d"; - document.getElementById("title2").textContent = "\uff0d"; - document.getElementById("iconn").textContent = "?"; - document.getElementById("iconc").textContent = "?"; - document.getElementById("icond").textContent = "?"; + resetDisplay(); if(filebox.files.length === 0) { return; } @@ -142,13 +150,7 @@ } psubox = document.getElementById("psuinput"); psubox.onchange = function(e) { - document.getElementById("title1").textContent = "\uff0d"; - document.getElementById("title2").textContent = "\uff0d"; - document.getElementById("iconn").textContent = "?"; - document.getElementById("iconc").textContent = "?"; - document.getElementById("icond").textContent = "?"; - document.getElementById("dateCreated").textContent = "--:--:-- --/--/----"; - document.getElementById("dateModified").textContent = "--:--:-- --/--/----"; + resetDisplay(); if(psubox.files.length === 0) { return; } @@ -173,6 +175,23 @@ } }); } + psvbox = document.getElementById("psvinput"); + psvbox.onchange = function(e) { + resetDisplay(); + if(psvbox.files.length === 0) { + return; + } + psvbox.files[0].arrayBuffer().then(function(d){ + try { + let inputData = readPsvFile(d); + let output = readPS2D(inputData["icon.sys"]); + updateDisplay(output); + } catch(e) { + if(glContext!==null){glContext.clear(glContext.COLOR_BUFFER_BIT);} + alert(e); + } + }); + } function createShader(gl, type, source) { var shader = gl.createShader(type); gl.shaderSource(shader, source); @@ -234,6 +253,7 @@ } //todo: Model rendering, animation parsing, animation tweening - icondumper2 0.3.2 - © 2023 yellows111 + icondumper2 (unknown icon.js version) - © 2023 yellows111 + \ No newline at end of file