A compatibility update.
No, this isn't a late 'Fool's joke, I was just having fun and now I can target pure ES6/ES2015 if I wanted to. …except Chakra ('Edge <= 44), that thing never implemented `TextDecoder`/`TextEncoder` for some reason. We'll never know why... I'm researching what makes over-bright happen... give me time!
This commit is contained in:
parent
5738fbb09c
commit
98edefff2e
52
README.md
52
README.md
|
@ -1,7 +1,20 @@
|
||||||
# icondumper2 (working title)
|
# icondumper2 (working title)
|
||||||
A JavaScript library (sorta) to read PS2 icons, and their related formats.
|
A JavaScript library (sorta) to read PS2 icons, and their related formats.
|
||||||
|
|
||||||
## What it supports
|
## What is a "PS2 icon"?
|
||||||
|
A set of vertices with may or may not include a texture while defining colours for those vertices.
|
||||||
|
|
||||||
|
## Why?
|
||||||
|
Current implementations had some issues with rendering some icons. These were mostly:
|
||||||
|
* Not rendering any color for texture type 3.
|
||||||
|
* Failing to decompress some specific RLE-compressed icons. (types above 8)
|
||||||
|
* Requires writing/reading a specific format for successful output of data.
|
||||||
|
|
||||||
|
As of writing, there was no exporter that exists for the format that exhibited one of these problems.
|
||||||
|
|
||||||
|
**icondumper2** is the result of me trying to avoid these problems.
|
||||||
|
|
||||||
|
## What it supports:
|
||||||
* EMS Memory Adapter export files (.psu)
|
* EMS Memory Adapter export files (.psu)
|
||||||
* PS3 virtual memory card export files (.psv)
|
* PS3 virtual memory card export files (.psv)
|
||||||
* SharkPort export files (.sps)
|
* SharkPort export files (.sps)
|
||||||
|
@ -9,30 +22,41 @@ A JavaScript library (sorta) to read PS2 icons, and their related formats.
|
||||||
* PS2 icons (.ico, .icn)
|
* PS2 icons (.ico, .icn)
|
||||||
* PS2D format (icon.sys)
|
* PS2D format (icon.sys)
|
||||||
|
|
||||||
## What can it do
|
## What can it do:
|
||||||
* Allow any file in a PSU's or SPS/XPS's virtual filesystem to be dumped.
|
* Allow any file in a supported virtual filesystem (such as those from export files) to be read.
|
||||||
* Warn of invalid icon.sys display names.
|
* Warn of invalid icon.sys display names.
|
||||||
* Read and parse an EMS MA export file.
|
* Export the icon model, with all seperate shapes included as a JavaScript Object.
|
||||||
* Export the icon model, with all seperate shapes included to a JavaScript Object.
|
* CommonJS (that includes node!) module exporting while still being compatible with other JavaScript implementations.
|
||||||
* Node.js compatible (CommonJS) exporting while still being compatible with other JavaScript implementations.
|
* Convert a 128x128x16 BGR5A1 bitmap to a standard RGB5A1 format.
|
||||||
* Convert a 128x128x16 BGR5A1 bitmap to a RGB5A1 format.
|
|
||||||
* Convert an icon or a set of icons to glTF 2, with textures saved as PNG.
|
* Convert an icon or a set of icons to glTF 2, with textures saved as PNG.
|
||||||
|
|
||||||
## What it doesn't do
|
## What it doesn't do:
|
||||||
* (Re)build save files.
|
* Create, manipulate or otherwise taint save files.
|
||||||
* Modify the original input files.
|
* Modify any original input files.
|
||||||
* Use any Node.js-exclusive features.
|
* Use any implementation-specific features.
|
||||||
|
|
||||||
## Client compatibility
|
## Client compatibility:
|
||||||
(todo: write this)
|
The library requires use of `const`, `let` and `class` declarations.
|
||||||
|
|
||||||
|
Any JavaScript implementation should work if they support all three of these declarations.
|
||||||
|
|
||||||
|
### Tested clients:
|
||||||
|
* Chrome (or Blink-based browser) 49 (or higher) - HTML reference client
|
||||||
|
* Firefox (or Gecko-based browser) 45 (or higher) - HTML reference client
|
||||||
|
* Node.js 13 (or higher) - Example client and glTF 2 exporter.
|
||||||
|
|
||||||
## Why "icondumper2"?
|
## Why "icondumper2"?
|
||||||
Because it replaced what *was* left of icondumper (1).
|
Because it replaced what *was* left of icondumper (1).
|
||||||
|
|
||||||
## Included files
|
## Included files:
|
||||||
| File | Description |
|
| File | Description |
|
||||||
| ---------------- | ----------------------------------------- |
|
| ---------------- | ----------------------------------------- |
|
||||||
| icon.js | The library itself. |
|
| icon.js | The library itself. |
|
||||||
| index.js | Node.js example client. |
|
| index.js | Node.js example client. |
|
||||||
| gltf-exporter.js | Node.js client to export icons to glTF 2. |
|
| gltf-exporter.js | Node.js client to export icons to glTF 2. |
|
||||||
| index.htm | HTML reference client. |
|
| index.htm | HTML reference client. |
|
||||||
|
|
||||||
|
## Included example files:
|
||||||
|
| Directory | Description | Formats |
|
||||||
|
| ------------ | ----------------------------------------- | -------- |
|
||||||
|
| /example_001 | A tetrahedron with all 3 base colors set. | PSU, SPS |
|
|
@ -249,7 +249,7 @@ function loadAndConvertIcon(inputData, attemptedFilename = "-") {
|
||||||
if (inputData.hasOwnProperty("numberOfShapes") === false) {
|
if (inputData.hasOwnProperty("numberOfShapes") === false) {
|
||||||
throw "Expected a icondumper2 Intermediate Model Format object.";
|
throw "Expected a icondumper2 Intermediate Model Format object.";
|
||||||
}
|
}
|
||||||
const filename = encodeURIComponent(attemptedFilename).replaceAll(/\%[0-9A-F]{2,2}/g, "").replaceAll(".", "_");
|
const filename = encodeURIComponent(attemptedFilename).replace(/\%[0-9A-F]{2,2}/g, "").replace(/\./g, "_");
|
||||||
const glTF_output = imf2gltf(inputData, filename);
|
const glTF_output = imf2gltf(inputData, filename);
|
||||||
for (let index = 0; index < (inputData.numberOfShapes); index++) {
|
for (let index = 0; index < (inputData.numberOfShapes); index++) {
|
||||||
(require("fs")).writeFileSync(`${filename}_${index}.gltf`, new TextEncoder().encode(JSON.stringify(glTF_output.objects[index])));
|
(require("fs")).writeFileSync(`${filename}_${index}.gltf`, new TextEncoder().encode(JSON.stringify(glTF_output.objects[index])));
|
||||||
|
|
30
icon.js
30
icon.js
|
@ -1,21 +1,22 @@
|
||||||
//todo: Make this a module/mjs file. C6 compatibility can stay, if needed.
|
//todo: Make this a module/mjs file. C6 compatibility can stay, if needed.
|
||||||
//LOOKING FOR: LZARI implementation (for MAX), description of CBS compression (node zlib doesn't tackle it, even with RC4'ing the data)
|
//LOOKING FOR: LZARI implementation (for MAX), description of CBS compression (node zlib doesn't tackle it, even with RC4'ing the data)
|
||||||
ICONJS_DEBUG = false;
|
var ICONJS_DEBUG = false;
|
||||||
ICONJS_STRICT = true;
|
var ICONJS_STRICT = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current version of the library.
|
* The current version of the library.
|
||||||
* @constant {string}
|
* @constant {string}
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
const ICONJS_VERSION = "0.6.1";
|
const ICONJS_VERSION = "0.6.1+u1";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension of DataView to add shortcuts for datatypes that I use often.
|
* Extension of DataView to add shortcuts for datatypes that I use often.
|
||||||
* @augments DataView
|
* @augments DataView
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {ArrayBuffer} buffer ArrayBuffer to base DataView from.
|
* @param {ArrayBuffer} buffer ArrayBuffer to base DataView from.
|
||||||
* @returns {Object.<string, function(number): number>}
|
* @returns {Object.<string, function(number): number>} [u16le, f16le, u32le, f32le]
|
||||||
|
* @returns {Object.<string, function(number): Object.<string.number>>} [t64le]
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
class yellowDataReader extends DataView {
|
class yellowDataReader extends DataView {
|
||||||
|
@ -40,9 +41,16 @@ class yellowDataReader extends DataView {
|
||||||
*/
|
*/
|
||||||
f32le(i){return super.getFloat32(i, 1)};
|
f32le(i){return super.getFloat32(i, 1)};
|
||||||
/** 64-bit Timestamp structure, Little Endian.
|
/** 64-bit Timestamp structure, Little Endian.
|
||||||
|
* Time returned is set for JST (UTC+09:00) instead of UTC.
|
||||||
* Time returned is going to be offseted for JST (GMT+09:00).
|
* Time returned is going to be offseted for JST (GMT+09:00).
|
||||||
* @param {number} i Indice offset.
|
* @param {number} i Indice offset.
|
||||||
* @returns {Object.<string, number>}
|
* @returns {Object.<string, number>}
|
||||||
|
* @property {number} seconds - Seconds.
|
||||||
|
* @property {number} minutes - Minutes.
|
||||||
|
* @property {number} hours - Hours.
|
||||||
|
* @property {number} day - Day.
|
||||||
|
* @property {number} month - Month.
|
||||||
|
* @property {number} year - Year.
|
||||||
*/
|
*/
|
||||||
t64le(i){return {
|
t64le(i){return {
|
||||||
seconds: super.getUint8(i+1),
|
seconds: super.getUint8(i+1),
|
||||||
|
@ -78,7 +86,7 @@ function setDebug(value) {
|
||||||
* Select if invalid characters in titles should be replaced with either spaces or nulls
|
* Select if invalid characters in titles should be replaced with either spaces or nulls
|
||||||
* @param {boolean} value - true: with nulls, false: with spaces
|
* @param {boolean} value - true: with nulls, false: with spaces
|
||||||
* @default true
|
* @default true
|
||||||
* @deprecated unlikely to ever need this?
|
* @deprecated Hasn't been needed for a while. Dropping support by ESM transition.
|
||||||
* @public
|
* @public
|
||||||
*/
|
*/
|
||||||
function setStrictness(value) {
|
function setStrictness(value) {
|
||||||
|
@ -182,7 +190,7 @@ function convertBGR5A1toRGB5A1(bgrData) {
|
||||||
* @access protected
|
* @access protected
|
||||||
*/
|
*/
|
||||||
function stringScrubber(dirty) {
|
function stringScrubber(dirty) {
|
||||||
return dirty.replaceAll("\x00","").substring(0, (dirty.indexOf("\x00") === -1) ? dirty.length : dirty.indexOf("\x00"));
|
return dirty.replace(/\0/g, "").substring(0, (dirty.indexOf("\x00") === -1) ? dirty.length : dirty.indexOf("\x00"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -627,9 +635,9 @@ function readSharkXPortSxpsFile(input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define (module.)exports with all public functions
|
* Define (module.)exports with all public functions.
|
||||||
* @exports icondumper2/icon
|
* @exports icondumper2/icon
|
||||||
*/
|
*/ // start c6js
|
||||||
exports = {
|
exports = {
|
||||||
readers: {readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile},
|
readers: {readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile},
|
||||||
helpers: {uncompressTexture, convertBGR5A1toRGB5A1},
|
helpers: {uncompressTexture, convertBGR5A1toRGB5A1},
|
||||||
|
@ -640,3 +648,9 @@ exports = {
|
||||||
if(typeof module !== "undefined") {
|
if(typeof module !== "undefined") {
|
||||||
module.exports = exports;
|
module.exports = exports;
|
||||||
}
|
}
|
||||||
|
//end c6js
|
||||||
|
//start esm
|
||||||
|
/*export {
|
||||||
|
readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile, uncompressTexture, convertBGR5A1toRGB5A1, setDebug, ICONJS_VERSION
|
||||||
|
};*/
|
||||||
|
//end esm
|
86
index.htm
86
index.htm
|
@ -20,6 +20,13 @@
|
||||||
input[type="file"] {line-height: 2em;}
|
input[type="file"] {line-height: 2em;}
|
||||||
#version {text-shadow: 1px 1px 2px black;}
|
#version {text-shadow: 1px 1px 2px black;}
|
||||||
a {color: #ccc;}
|
a {color: #ccc;}
|
||||||
|
.inputbox {
|
||||||
|
display: inline-grid;
|
||||||
|
margin-right: 0.25em;
|
||||||
|
border: 1px gray solid;
|
||||||
|
padding: 0.175em 0.25em 0 0.25em;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<meta data-comment="WebGL Shader: Icon">
|
<meta data-comment="WebGL Shader: Icon">
|
||||||
<script type="text/plain" id="shader-icon-v">
|
<script type="text/plain" id="shader-icon-v">
|
||||||
|
@ -133,15 +140,18 @@
|
||||||
<br>
|
<br>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
<div class="inputbox">
|
||||||
<label for="psuinput">EMS Memory Adapter export file (.psu) goes here:</label>
|
<label for="psuinput">EMS Memory Adapter export file (.psu) goes here:</label>
|
||||||
<input type="file" id="psuinput" name="psuinput" accept=".psu" />
|
<input type="file" id="psuinput" name="psuinput" accept=".psu" />
|
||||||
<br>
|
</div>
|
||||||
|
<div class="inputbox">
|
||||||
<label for="psvinput">PS3 export file (.psv) goes here:</label>
|
<label for="psvinput">PS3 export file (.psv) goes here:</label>
|
||||||
<input type="file" id="psvinput" name="psvinput" accept=".psv" />
|
<input type="file" id="psvinput" name="psvinput" accept=".psv" />
|
||||||
<br>
|
</div>
|
||||||
|
<div class="inputbox">
|
||||||
<label for="spsinput">SharkPort/X-Port export file (.sps, .xps) goes here:</label>
|
<label for="spsinput">SharkPort/X-Port export file (.sps, .xps) goes here:</label>
|
||||||
<input type="file" id="spsinput" name="spsinput" accept=".sps, .xps" />
|
<input type="file" id="spsinput" name="spsinput" accept=".sps, .xps" />
|
||||||
<br>
|
</div>
|
||||||
<p>
|
<p>
|
||||||
<span>Date created: </span><span id="dateCreated">--:--:-- --/--/----</span><span> UTC+09:00</span>
|
<span>Date created: </span><span id="dateCreated">--:--:-- --/--/----</span><span> UTC+09:00</span>
|
||||||
<wbr><span>–</span>
|
<wbr><span>–</span>
|
||||||
|
@ -152,16 +162,19 @@
|
||||||
</p>
|
</p>
|
||||||
<script>
|
<script>
|
||||||
// I usually don't do in-body <script>'s, but I didn't want to do an await onload() again
|
// I usually don't do in-body <script>'s, but I didn't want to do an await onload() again
|
||||||
const GlobalState = {rotations: 2, dataLength: 0, uniforms: {rotation: null, scale: null}, iconState: {source: null, currentIcon: null, currentSubmodel: 0, cachedIconSys: null}};
|
const GlobalState = {rotations: 2, dataLength: 0, uniforms: {rotation: null, scale: null}, iconState: {source: null, currentIcon: null, currentSubmodel: 0, cachedIconSys: null}, fileReader: (new FileReader)};
|
||||||
// I don't care HOW disgusting doing this is, I'm sick of pressing escape to clear these.
|
// I don't care HOW disgusting doing this is, I'm sick of pressing escape to clear these.
|
||||||
let allInputs = document.querySelectorAll('input[type="file"]');
|
let allInputs = document.querySelectorAll('input[type="file"]');
|
||||||
allInputs.forEach(
|
Array.from(allInputs).forEach(
|
||||||
function(nodeObject) {
|
function(nodeObject) {
|
||||||
nodeObject.onclick = function() {
|
nodeObject.onclick = function() {
|
||||||
allInputs.forEach(function(elementObject) {elementObject.value = null;});
|
Array.from(allInputs).forEach(function(elementObject) {elementObject.value = null;});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
function p0in(input) { // "prefix 0 if needed"
|
||||||
|
return ((input.length>=2) ? input : `0${input}`);
|
||||||
|
};
|
||||||
// rotation stuff
|
// rotation stuff
|
||||||
const rotationDensity = 60;
|
const rotationDensity = 60;
|
||||||
document.body.onkeydown = function(ev) {
|
document.body.onkeydown = function(ev) {
|
||||||
|
@ -394,7 +407,7 @@
|
||||||
//.section LIGHTING
|
//.section LIGHTING
|
||||||
let colours = fileMetadata.lighting.colors[0];
|
let colours = fileMetadata.lighting.colors[0];
|
||||||
//glFgContext.uniform3f(uniforms.ambientLighting, colours.r, colours.g, colours.b);
|
//glFgContext.uniform3f(uniforms.ambientLighting, colours.r, colours.g, colours.b);
|
||||||
glFgContext.uniform3f(uniforms.ambientLighting, 1, 1, 1);
|
glFgContext.uniform3f(uniforms.ambientLighting, 0.75, 0.75, 0.75);
|
||||||
|
|
||||||
//.section SCALING
|
//.section SCALING
|
||||||
GlobalState.uniforms.scale = uniforms.scale;
|
GlobalState.uniforms.scale = uniforms.scale;
|
||||||
|
@ -421,25 +434,30 @@
|
||||||
if(filebox.files.length === 0) {
|
if(filebox.files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
filebox.files[0].arrayBuffer().then(function(d){
|
GlobalState.fileReader.readAsArrayBuffer(filebox.files[0]);
|
||||||
|
GlobalState.fileReader.onloadend = function() {
|
||||||
|
GlobalState.fileReader.onloadend = void(0);
|
||||||
try {
|
try {
|
||||||
let output = readPS2D(d);
|
let output = readPS2D(GlobalState.fileReader.result);
|
||||||
console.info("icon.sys", output);
|
console.info("icon.sys", output);
|
||||||
updateDisplay(output);
|
updateDisplay(output);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
||||||
|
console.error(e);
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
iconbox = document.getElementById("icon");
|
iconbox = document.getElementById("icon");
|
||||||
iconbox.onchange = function(e) {
|
iconbox.onchange = function(e) {
|
||||||
if(iconbox.files.length === 0) {
|
if(iconbox.files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
iconbox.files[0].arrayBuffer().then(function(d){
|
GlobalState.fileReader.readAsArrayBuffer(iconbox.files[0]);
|
||||||
|
GlobalState.fileReader.onloadend = function() {
|
||||||
|
GlobalState.fileReader.onloadend = void(0);
|
||||||
try {
|
try {
|
||||||
let output = readIconFile(d);
|
let output = readIconFile(GlobalState.fileReader.result);
|
||||||
GlobalState.iconState.cachedIconSys = null;
|
GlobalState.iconState.cachedIconSys = null;
|
||||||
GlobalState.iconState.source = null;
|
GlobalState.iconState.source = null;
|
||||||
GlobalState.iconState.currentSubmodel = 0;
|
GlobalState.iconState.currentSubmodel = 0;
|
||||||
|
@ -448,9 +466,10 @@
|
||||||
console.info("model data (ic*)",output);
|
console.info("model data (ic*)",output);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
||||||
|
console.error(e);
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
psubox = document.getElementById("psuinput");
|
psubox = document.getElementById("psuinput");
|
||||||
psubox.onchange = function(e) {
|
psubox.onchange = function(e) {
|
||||||
|
@ -458,9 +477,11 @@
|
||||||
if(psubox.files.length === 0) {
|
if(psubox.files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
psubox.files[0].arrayBuffer().then(function(d){
|
GlobalState.fileReader.readAsArrayBuffer(psubox.files[0]);
|
||||||
|
GlobalState.fileReader.onloadend = function() {
|
||||||
|
GlobalState.fileReader.onloadend = void(0);
|
||||||
try {
|
try {
|
||||||
let vFilesystem = readEmsPsuFile(d);
|
let vFilesystem = readEmsPsuFile(GlobalState.fileReader.result);
|
||||||
let output = readPS2D(vFilesystem[vFilesystem.rootDirectory]["icon.sys"].data);
|
let output = readPS2D(vFilesystem[vFilesystem.rootDirectory]["icon.sys"].data);
|
||||||
updateDisplay(output);
|
updateDisplay(output);
|
||||||
let output2 = new Object();
|
let output2 = new Object();
|
||||||
|
@ -475,16 +496,17 @@
|
||||||
let cTime = vFilesystem.timestamps.created;
|
let cTime = vFilesystem.timestamps.created;
|
||||||
let mTime = vFilesystem.timestamps.modified;
|
let mTime = vFilesystem.timestamps.modified;
|
||||||
//TODO: use Time() to align JST times to user-local timezone
|
//TODO: use Time() to align JST times to user-local timezone
|
||||||
document.getElementById("dateCreated").textContent = `${cTime.hours.toString().padStart("2","0")}:${cTime.minutes.toString().padStart("2","0")}:${cTime.seconds.toString().padStart("2","0")} ${cTime.day.toString().padStart("2","0")}/${cTime.month.toString().padStart("2","0")}/${cTime.year}`;
|
document.getElementById("dateCreated").textContent = `${p0in(cTime.hours.toString())}:${p0in(cTime.minutes.toString())}:${p0in(cTime.seconds.toString())} ${p0in(cTime.day.toString())}/${p0in(cTime.month.toString())}/${cTime.year}`;
|
||||||
document.getElementById("dateModified").textContent = `${mTime.hours.toString().padStart("2","0")}:${mTime.minutes.toString().padStart("2","0")}:${mTime.seconds.toString().padStart("2","0")} ${mTime.day.toString().padStart("2","0")}/${mTime.month.toString().padStart("2","0")}/${mTime.year}`;
|
document.getElementById("dateModified").textContent = `${p0in(mTime.hours.toString())}:${p0in(mTime.minutes.toString())}:${p0in(mTime.seconds.toString())} ${p0in(mTime.day.toString())}/${p0in(mTime.month.toString())}/${mTime.year}`;
|
||||||
console.info("model files (psu)", output2);
|
console.info("model files (psu)", output2);
|
||||||
console.info("icon.sys (psu)", output);
|
console.info("icon.sys (psu)", output);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
||||||
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
||||||
|
console.error(e);
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
psvbox = document.getElementById("psvinput");
|
psvbox = document.getElementById("psvinput");
|
||||||
psvbox.onchange = function(e) {
|
psvbox.onchange = function(e) {
|
||||||
|
@ -492,9 +514,11 @@
|
||||||
if(psvbox.files.length === 0) {
|
if(psvbox.files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
psvbox.files[0].arrayBuffer().then(function(d){
|
GlobalState.fileReader.readAsArrayBuffer(psvbox.files[0]);
|
||||||
|
GlobalState.fileReader.onloadend = function() {
|
||||||
|
GlobalState.fileReader.onloadend = void(0);
|
||||||
try {
|
try {
|
||||||
let inputData = readPsvFile(d);
|
let inputData = readPsvFile(GlobalState.fileReader.result);
|
||||||
let output = readPS2D(inputData["icon.sys"]);
|
let output = readPS2D(inputData["icon.sys"]);
|
||||||
updateDisplay(output);
|
updateDisplay(output);
|
||||||
const icons = {
|
const icons = {
|
||||||
|
@ -510,16 +534,17 @@
|
||||||
let cTime = inputData.timestamps.created;
|
let cTime = inputData.timestamps.created;
|
||||||
let mTime = inputData.timestamps.modified;
|
let mTime = inputData.timestamps.modified;
|
||||||
//TODO: use Time() to align JST times to user-local timezone
|
//TODO: use Time() to align JST times to user-local timezone
|
||||||
document.getElementById("dateCreated").textContent = `${cTime.hours.toString().padStart("2","0")}:${cTime.minutes.toString().padStart("2","0")}:${cTime.seconds.toString().padStart("2","0")} ${cTime.day.toString().padStart("2","0")}/${cTime.month.toString().padStart("2","0")}/${cTime.year}`;
|
document.getElementById("dateCreated").textContent = `${p0in(cTime.hours.toString())}:${p0in(cTime.minutes.toString())}:${p0in(cTime.seconds.toString())} ${p0in(cTime.day.toString())}/${p0in(cTime.month.toString())}/${cTime.year}`;
|
||||||
document.getElementById("dateModified").textContent = `${mTime.hours.toString().padStart("2","0")}:${mTime.minutes.toString().padStart("2","0")}:${mTime.seconds.toString().padStart("2","0")} ${mTime.day.toString().padStart("2","0")}/${mTime.month.toString().padStart("2","0")}/${mTime.year}`;
|
document.getElementById("dateModified").textContent = `${p0in(mTime.hours.toString())}:${p0in(mTime.minutes.toString())}:${p0in(mTime.seconds.toString())} ${p0in(mTime.day.toString())}/${p0in(mTime.month.toString())}/${mTime.year}`;
|
||||||
console.info("model files (psv)", icons);
|
console.info("model files (psv)", icons);
|
||||||
console.info("icon.sys (psv)", output);
|
console.info("icon.sys (psv)", output);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
||||||
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
||||||
|
console.error(e);
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
spsbox = document.getElementById("spsinput");
|
spsbox = document.getElementById("spsinput");
|
||||||
spsbox.onchange = function(e) {
|
spsbox.onchange = function(e) {
|
||||||
|
@ -527,9 +552,11 @@
|
||||||
if(spsbox.files.length === 0) {
|
if(spsbox.files.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
spsbox.files[0].arrayBuffer().then(function(d){
|
GlobalState.fileReader.readAsArrayBuffer(spsbox.files[0]);
|
||||||
|
GlobalState.fileReader.onloadend = function() {
|
||||||
|
GlobalState.fileReader.onloadend = void(0);
|
||||||
try {
|
try {
|
||||||
let vFilesystem = readSharkXPortSxpsFile(d);
|
let vFilesystem = readSharkXPortSxpsFile(GlobalState.fileReader.result);
|
||||||
let output = readPS2D(vFilesystem[vFilesystem.rootDirectory]["icon.sys"].data);
|
let output = readPS2D(vFilesystem[vFilesystem.rootDirectory]["icon.sys"].data);
|
||||||
updateDisplay(output);
|
updateDisplay(output);
|
||||||
let output2 = new Object();
|
let output2 = new Object();
|
||||||
|
@ -544,8 +571,8 @@
|
||||||
let cTime = vFilesystem.timestamps.created;
|
let cTime = vFilesystem.timestamps.created;
|
||||||
let mTime = vFilesystem.timestamps.modified;
|
let mTime = vFilesystem.timestamps.modified;
|
||||||
//TODO: use Time() to align JST times to user-local timezone
|
//TODO: use Time() to align JST times to user-local timezone
|
||||||
document.getElementById("dateCreated").textContent = `${cTime.hours.toString().padStart("2","0")}:${cTime.minutes.toString().padStart("2","0")}:${cTime.seconds.toString().padStart("2","0")} ${cTime.day.toString().padStart("2","0")}/${cTime.month.toString().padStart("2","0")}/${cTime.year}`;
|
document.getElementById("dateCreated").textContent = `${p0in(cTime.hours.toString())}:${p0in(cTime.minutes.toString())}:${p0in(cTime.seconds.toString())} ${p0in(cTime.day.toString())}/${p0in(cTime.month.toString())}/${cTime.year}`;
|
||||||
document.getElementById("dateModified").textContent = `${mTime.hours.toString().padStart("2","0")}:${mTime.minutes.toString().padStart("2","0")}:${mTime.seconds.toString().padStart("2","0")} ${mTime.day.toString().padStart("2","0")}/${mTime.month.toString().padStart("2","0")}/${mTime.year}`;
|
document.getElementById("dateModified").textContent = `${p0in(mTime.hours.toString())}:${p0in(mTime.minutes.toString())}:${p0in(mTime.seconds.toString())} ${p0in(mTime.day.toString())}/${p0in(mTime.month.toString())}/${mTime.year}`;
|
||||||
document.getElementById("fileCommentGame").textContent = vFilesystem.comments.game;
|
document.getElementById("fileCommentGame").textContent = vFilesystem.comments.game;
|
||||||
document.getElementById("fileCommentName").textContent = vFilesystem.comments.name;
|
document.getElementById("fileCommentName").textContent = vFilesystem.comments.name;
|
||||||
if(vFilesystem.comments.hasOwnProperty("desc")) {
|
if(vFilesystem.comments.hasOwnProperty("desc")) {
|
||||||
|
@ -556,9 +583,10 @@
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
||||||
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
||||||
|
console.error(e);
|
||||||
alert(e);
|
alert(e);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
function createShader(gl, type, source) {
|
function createShader(gl, type, source) {
|
||||||
let shader = gl.createShader(type);
|
let shader = gl.createShader(type);
|
||||||
|
@ -639,7 +667,7 @@
|
||||||
<span id="version">icondumper2 <a href="./documentation" id="iconjsVersion">(unknown icon.js version)</a> [C: <span id="clientVersion">Loading...</span>] — © <span id="currentYear">2023</span> yellows111</span>
|
<span id="version">icondumper2 <a href="./documentation" id="iconjsVersion">(unknown icon.js version)</a> [C: <span id="clientVersion">Loading...</span>] — © <span id="currentYear">2023</span> yellows111</span>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("iconjsVersion").textContent = exports.version;
|
document.getElementById("iconjsVersion").textContent = exports.version;
|
||||||
document.getElementById("clientVersion").textContent = "0.6.6";
|
document.getElementById("clientVersion").textContent = "0.6.7";
|
||||||
document.getElementById("currentYear").textContent = (new Date()).getFullYear().toString();
|
document.getElementById("currentYear").textContent = (new Date()).getFullYear().toString();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
Loading…
Reference in New Issue