0.8.0 (actually) forgot to -a
This commit is contained in:
parent
eb8bc8e068
commit
23ef7c7ca1
|
@ -14,7 +14,7 @@ jobs:
|
||||||
- name: Install node.js
|
- name: Install node.js
|
||||||
uses: actions/setup-node@main
|
uses: actions/setup-node@main
|
||||||
- name: Compile documentation with JSDoc
|
- name: Compile documentation with JSDoc
|
||||||
run: npx jsdoc ./icon.js -d ./documentation -R ./README.md
|
run: npx jsdoc ./icon.js ./lzari.js -d ./documentation -R ./README.md
|
||||||
- name: Upload Artifacts
|
- name: Upload Artifacts
|
||||||
uses: actions/upload-artifact@main
|
uses: actions/upload-artifact@main
|
||||||
with:
|
with:
|
||||||
|
|
|
@ -13,6 +13,8 @@ icon.sys
|
||||||
*.p2m
|
*.p2m
|
||||||
*.md
|
*.md
|
||||||
*.cbs
|
*.cbs
|
||||||
|
*.max
|
||||||
|
*.pws
|
||||||
|
|
||||||
# Unused data
|
# Unused data
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ As of writing, there was no exporter that exists for the format that exhibited o
|
||||||
* SharkPort export files (.sps)
|
* SharkPort export files (.sps)
|
||||||
* X-Port export files (.xps)
|
* X-Port export files (.xps)
|
||||||
* CodeBreaker Save export files (.cbs)
|
* CodeBreaker Save export files (.cbs)
|
||||||
|
* Max Drive "PowerSave"/export files (.max)
|
||||||
* PS2 icons (.ico, .icn)
|
* PS2 icons (.ico, .icn)
|
||||||
* PS2D format (icon.sys)
|
* PS2D format (icon.sys)
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ As of writing, there was no exporter that exists for the format that exhibited o
|
||||||
* CommonJS (that includes node!) module exporting while still being compatible with other JavaScript implementations.
|
* CommonJS (that includes node!) module 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 standard 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.
|
||||||
|
* Decompress any LZARI-formatted data.
|
||||||
|
|
||||||
## What it doesn't do:
|
## What it doesn't do:
|
||||||
* Create, manipulate or otherwise taint save files.
|
* Create, manipulate or otherwise taint save files.
|
||||||
|
@ -56,6 +58,7 @@ Because it replaced what *was* left of icondumper (1).
|
||||||
| 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. |
|
||||||
|
| lzari.js | A LZARI decompression-only library. |
|
||||||
|
|
||||||
## Included example files:
|
## Included example files:
|
||||||
| Directory | Description | Formats |
|
| Directory | Description | Formats |
|
||||||
|
|
|
@ -322,6 +322,23 @@ switch(processObj.argv[2]) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "max":
|
||||||
|
case "pws": {
|
||||||
|
let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "file.max");
|
||||||
|
function myUnlzari(inputBuffer) {
|
||||||
|
return (require("./lzari.js").decodeLzari(inputBuffer)).buffer;
|
||||||
|
}
|
||||||
|
const parsed = iconjs.readMaxPwsFile(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength), myUnlzari);
|
||||||
|
const PS2D = iconjs.readPS2D(parsed[parsed.rootDirectory]["icon.sys"].data);
|
||||||
|
loadAndConvertIcon(iconjs.readIconFile(parsed[parsed.rootDirectory][PS2D.filenames.n].data), PS2D.filenames.n);
|
||||||
|
if(PS2D.filenames.n !== PS2D.filenames.c) {
|
||||||
|
loadAndConvertIcon(iconjs.readIconFile(parsed[parsed.rootDirectory][PS2D.filenames.c].data), PS2D.filenames.c);
|
||||||
|
}
|
||||||
|
if(PS2D.filenames.n !== PS2D.filenames.d) {
|
||||||
|
loadAndConvertIcon(iconjs.readIconFile(parsed[parsed.rootDirectory][PS2D.filenames.d].data), PS2D.filenames.d);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "sys": {
|
case "sys": {
|
||||||
let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "icon.sys");
|
let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "icon.sys");
|
||||||
const PS2D = iconjs.readPS2D(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength));
|
const PS2D = iconjs.readPS2D(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength));
|
||||||
|
@ -352,6 +369,8 @@ psv: Read a PS3 export file.
|
||||||
sps: Read a SharkPort export file.
|
sps: Read a SharkPort export file.
|
||||||
xps: Read a X-Port export file.
|
xps: Read a X-Port export file.
|
||||||
cbs: Read a CodeBreaker Save export file.
|
cbs: Read a CodeBreaker Save export file.
|
||||||
|
max: Read a Max Drive export file.
|
||||||
|
pws: Read a PowerSave export file.
|
||||||
|
|
||||||
sys: Read a icon.sys (964 bytes) file, and attempt
|
sys: Read a icon.sys (964 bytes) file, and attempt
|
||||||
to read icon files from the current directory.
|
to read icon files from the current directory.
|
||||||
|
|
91
icon.js
91
icon.js
|
@ -1,5 +1,4 @@
|
||||||
//To swap between mjs/esm and c6js, go to the end of this file, and (un)comment your wanted module mode.
|
//To swap between mjs/esm and c6js, go to the end of this file, and (un)comment your wanted module mode.
|
||||||
//LOOKING FOR: LZARI implementation (for MAX and PWS files. THIS WILL COMPLETE ICONDUMPER2.)
|
|
||||||
var ICONJS_DEBUG = false;
|
var ICONJS_DEBUG = false;
|
||||||
var ICONJS_STRICT = true;
|
var ICONJS_STRICT = true;
|
||||||
|
|
||||||
|
@ -8,7 +7,7 @@ var ICONJS_STRICT = true;
|
||||||
* @constant {string}
|
* @constant {string}
|
||||||
* @default
|
* @default
|
||||||
*/
|
*/
|
||||||
const ICONJS_VERSION = "0.7.0";
|
const ICONJS_VERSION = "0.8.0";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The RC4 key used for ciphering CodeBreaker Saves.
|
* The RC4 key used for ciphering CodeBreaker Saves.
|
||||||
|
@ -488,7 +487,7 @@ function readEntryBlock(input) {
|
||||||
function readEmsPsuFile(input){
|
function readEmsPsuFile(input){
|
||||||
const header = readEntryBlock(input.slice(0,0x1ff));
|
const header = readEntryBlock(input.slice(0,0x1ff));
|
||||||
if(header.size > 0x7f) {
|
if(header.size > 0x7f) {
|
||||||
throw `Directory is too large! (maximum size: ${0x7f}, was ${header.size})`
|
throw `Directory is too large! (maximum size: ${0x7f}, was ${header.size})`;
|
||||||
}
|
}
|
||||||
let fsOut = {length: header.size, rootDirectory: header.filename, timestamps: header.timestamps};
|
let fsOut = {length: header.size, rootDirectory: header.filename, timestamps: header.timestamps};
|
||||||
let output = new Object();
|
let output = new Object();
|
||||||
|
@ -637,7 +636,7 @@ function readSharkXPortSxpsFile(input) {
|
||||||
let offset = 4;
|
let offset = 4;
|
||||||
const ident = input.slice(offset, offset+identLength);
|
const ident = input.slice(offset, offset+identLength);
|
||||||
if((new TextDecoder("utf-8")).decode(ident) !== "SharkPortSave") {
|
if((new TextDecoder("utf-8")).decode(ident) !== "SharkPortSave") {
|
||||||
throw `Unrecognized file identification string. Expected "SharkPortSave".`
|
throw `Unrecognized file identification string. Expected "SharkPortSave".`;
|
||||||
}
|
}
|
||||||
offset += (identLength + 4);
|
offset += (identLength + 4);
|
||||||
const titleLength = u32le(offset);
|
const titleLength = u32le(offset);
|
||||||
|
@ -756,19 +755,95 @@ function readCodeBreakerCbsFile(input, inflator = null) {
|
||||||
const inflatedData = inflator(decipheredData);
|
const inflatedData = inflator(decipheredData);
|
||||||
const fsOut = {rootDirectory: dirName, timestamps};
|
const fsOut = {rootDirectory: dirName, timestamps};
|
||||||
fsOut[dirName] = readCodeBreakerCbsDirectory(inflatedData);
|
fsOut[dirName] = readCodeBreakerCbsDirectory(inflatedData);
|
||||||
|
if(ICONJS_DEBUG) {
|
||||||
|
console.debug({magic, dataOffset, compressedSize, dirName, permissions, displayName});
|
||||||
|
}
|
||||||
return fsOut;
|
return fsOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a Max Drive (MAX) or PowerSave (PWS) file's directory structure.
|
||||||
|
* @param {ArrayBuffer} input - Uncompressed input
|
||||||
|
* @returns {Object} (user didn't write a description)
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
function readMaxPwsDirectory(input, directorySize) {
|
||||||
|
const {u32le} = new yellowDataReader(input);
|
||||||
|
virtualFilesystem = new Object();
|
||||||
|
let offset = 0;
|
||||||
|
for (let index = 0; index < directorySize; index++) {
|
||||||
|
const dataSize = u32le(offset);
|
||||||
|
const _filename = input.slice(offset+4, offset+36);
|
||||||
|
const filename = stringScrubber((new TextDecoder("utf-8")).decode(_filename));
|
||||||
|
if(filename === "") { throw `Unexpected null filename at byte ${offset+4}.`; };
|
||||||
|
offset += 36;
|
||||||
|
const data = input.slice(offset, offset+dataSize);
|
||||||
|
offset += dataSize;
|
||||||
|
if(index !== directorySize - 1) {
|
||||||
|
while((offset & 15) !== 8) {
|
||||||
|
offset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtualFilesystem[filename] = ({dataSize, data});
|
||||||
|
}
|
||||||
|
return virtualFilesystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a Max Drive (MAX) or PowerSave (PWS) file.
|
||||||
|
* @param {ArrayBuffer} input - MAX/PWS formatted file
|
||||||
|
* @param {function(Uint8Array): ArrayBuffer} unlzari - a function which provides a LZARI-compatible decompression function.
|
||||||
|
* @returns {Object} (user didn't write a description)
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
function readMaxPwsFile(input, unlzari) {
|
||||||
|
if(typeof unlzari !== "function") {
|
||||||
|
throw `No decompresser function passed. Skipping.`;
|
||||||
|
}
|
||||||
|
const {u32le} = new yellowDataReader(input);
|
||||||
|
const ident = input.slice(0, 12);
|
||||||
|
if((new TextDecoder("utf-8")).decode(ident) !== "Ps2PowerSave") {
|
||||||
|
throw `Unrecognized file identification string. Expected "Ps2PowerSave".`;
|
||||||
|
}
|
||||||
|
//:skip 4 (u32 checksum)
|
||||||
|
const _dirName = input.slice(0x10, 0x30);
|
||||||
|
const dirName = stringScrubber((new TextDecoder("utf-8")).decode(_dirName));
|
||||||
|
const _displayName = input.slice(0x30, 0x50);
|
||||||
|
const displayName = stringScrubber((new TextDecoder("utf-8")).decode(_displayName));
|
||||||
|
const compressedSize = u32le(0x50);
|
||||||
|
if(compressedSize !== (input.byteLength - 88)) {
|
||||||
|
console.warn(`This file says it's larger then it actually is! (Given size: ${compressedSize}, actual size: ${input.byteLength - 88})`);
|
||||||
|
}
|
||||||
|
const size = u32le(0x54);
|
||||||
|
const compressedData = input.slice(88, input.byteLength);
|
||||||
|
const uncompressedData = unlzari(new Uint8Array(compressedData)); // read above why we can't trust given size
|
||||||
|
const fsOut = {rootDirectory: dirName};
|
||||||
|
fsOut[dirName] = readMaxPwsDirectory(uncompressedData, size);
|
||||||
|
// there's no... timestamps or permissions... this doesn't bode well.
|
||||||
|
if(ICONJS_DEBUG) {
|
||||||
|
console.debug({ident, compressedSize, dirName, displayName});
|
||||||
|
}
|
||||||
|
return fsOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define (module.)exports with all public functions.
|
* Define (module.)exports with all public functions.
|
||||||
* @exports icondumper2/icon
|
* @exports icondumper2/icon
|
||||||
*/ // start c6js
|
*/ // start c6js
|
||||||
exports = {
|
if(typeof exports !== "object") {
|
||||||
readers: {readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile, readCodeBreakerCbsFile},
|
exports = {
|
||||||
|
readers: {readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile, readCodeBreakerCbsFile, readMaxPwsFile},
|
||||||
helpers: {uncompressTexture, convertBGR5A1toRGB5A1},
|
helpers: {uncompressTexture, convertBGR5A1toRGB5A1},
|
||||||
options: {setDebug, setStrictness},
|
options: {setDebug, setStrictness},
|
||||||
version: ICONJS_VERSION
|
version: ICONJS_VERSION
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
exports.readers = {readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile, readCodeBreakerCbsFile, readMaxPwsFile};
|
||||||
|
exports.helpers = {uncompressTexture, convertBGR5A1toRGB5A1};
|
||||||
|
exports.options = {setDebug, setStrictness};
|
||||||
|
exports.version = ICONJS_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
if(typeof module !== "undefined") {
|
if(typeof module !== "undefined") {
|
||||||
module.exports = exports;
|
module.exports = exports;
|
||||||
|
@ -776,6 +851,6 @@ if(typeof module !== "undefined") {
|
||||||
//end c6js
|
//end c6js
|
||||||
//start esm
|
//start esm
|
||||||
/*export {
|
/*export {
|
||||||
readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile, readCodeBreakerCbsFile, uncompressTexture, convertBGR5A1toRGB5A1, setDebug, ICONJS_VERSION
|
readIconFile, readPS2D, readEmsPsuFile, readPsvFile, readSharkXPortSxpsFile, readCodeBreakerCbsFile, readMaxPwsFile, uncompressTexture, convertBGR5A1toRGB5A1, setDebug, ICONJS_VERSION
|
||||||
};*/
|
};*/
|
||||||
//end esm
|
//end esm
|
61
index.htm
61
index.htm
|
@ -6,6 +6,7 @@
|
||||||
<meta name="description" content="A HTML client for icondumper2"></meta>
|
<meta name="description" content="A HTML client for icondumper2"></meta>
|
||||||
<title>icondumper2 - HTML reference client</title>
|
<title>icondumper2 - HTML reference client</title>
|
||||||
<script src="icon.js"></script>
|
<script src="icon.js"></script>
|
||||||
|
<script src="lzari.js"></script>
|
||||||
<!-- If you need pako to be optional, remove/comment the bottom line. This will disable support for CBS reading, however -->
|
<!-- If you need pako to be optional, remove/comment the bottom line. This will disable support for CBS reading, however -->
|
||||||
<script src="https://cdn.jsdelivr.net/npm/pako/dist/pako_inflate.es5.min.js" integrity="sha512-tHdgbM+jAAm3zeGYP67IjUouqHYEMuT/Wg/xvTrfEE7zsSX2GJj0G26pyobvn8Hb2LVWGp+UwsLM2HvXwCY+og==" crossorigin="anonymous"></script>
|
<script src="https://cdn.jsdelivr.net/npm/pako/dist/pako_inflate.es5.min.js" integrity="sha512-tHdgbM+jAAm3zeGYP67IjUouqHYEMuT/Wg/xvTrfEE7zsSX2GJj0G26pyobvn8Hb2LVWGp+UwsLM2HvXwCY+og==" crossorigin="anonymous"></script>
|
||||||
<style>
|
<style>
|
||||||
|
@ -33,6 +34,9 @@
|
||||||
.last-input {
|
.last-input {
|
||||||
border-right: 1px gray solid;
|
border-right: 1px gray solid;
|
||||||
}
|
}
|
||||||
|
.inputbox > input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
</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">
|
||||||
|
@ -137,31 +141,35 @@
|
||||||
<div id="advanced">
|
<div id="advanced">
|
||||||
<hr>
|
<hr>
|
||||||
<div class="inputbox">
|
<div class="inputbox">
|
||||||
<label for="input">icon.sys goes here:</label>
|
<label for="input">icon.sys:</label>
|
||||||
<input type="file" id="input" name="input" accept=".sys" />
|
<input type="file" id="input" name="input" accept=".sys" />
|
||||||
</div>
|
</div>
|
||||||
<div class="inputbox last-input">
|
<div class="inputbox last-input">
|
||||||
<label for="icon">raw icon file goes here:</label>
|
<label for="icon">raw icon file:</label>
|
||||||
<input type="file" id="icon" name="icon" accept=".icn, .ico" />
|
<input type="file" id="icon" name="icon" accept=".icn, .ico" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="inputbox">
|
<div class="inputbox">
|
||||||
<label for="psuinput">EMS Memory Adapter export file (.psu) goes here:</label>
|
<label for="psuinput">EMS Memory Adapter export file (.psu):</label>
|
||||||
<input type="file" id="psuinput" name="psuinput" accept=".psu" />
|
<input type="file" id="psuinput" name="psuinput" accept=".psu" />
|
||||||
</div>
|
</div>
|
||||||
<div class="inputbox">
|
<div class="inputbox">
|
||||||
<label for="psvinput">PS3 export file (.psv) goes here:</label>
|
<label for="psvinput">PS3 export file (.psv):</label>
|
||||||
<input type="file" id="psvinput" name="psvinput" accept=".psv" />
|
<input type="file" id="psvinput" name="psvinput" accept=".psv" />
|
||||||
</div>
|
</div>
|
||||||
<div class="inputbox">
|
<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):</label>
|
||||||
<input type="file" id="spsinput" name="spsinput" accept=".sps, .xps" />
|
<input type="file" id="spsinput" name="spsinput" accept=".sps, .xps" />
|
||||||
</div>
|
</div>
|
||||||
<div class="inputbox last-input">
|
<div class="inputbox">
|
||||||
<label for="cbsinput">CodeBreaker Save export file (.cbs) goes here:</label>
|
<label for="cbsinput">CodeBreaker Save export file (.cbs):</label>
|
||||||
<input type="file" id="cbsinput" name="cbsinput" accept=".cbs" />
|
<input type="file" id="cbsinput" name="cbsinput" accept=".cbs" />
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inputbox last-input">
|
||||||
|
<label for="maxinput">Max Drive/PowerSave export file (.max):</label>
|
||||||
|
<input type="file" id="maxinput" name="maxinput" accept=".max, .pws" />
|
||||||
|
</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>
|
||||||
|
@ -305,8 +313,10 @@
|
||||||
GlobalState.rotations = 2;
|
GlobalState.rotations = 2;
|
||||||
GlobalState.iconState.currentSubmodel = 0;
|
GlobalState.iconState.currentSubmodel = 0;
|
||||||
//clear buffers
|
//clear buffers
|
||||||
|
if(glFgContext !== null) {
|
||||||
glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);
|
glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
function renderIcon(iconData, fileMetadata = null, clearData = true) {
|
function renderIcon(iconData, fileMetadata = null, clearData = true) {
|
||||||
if(fileMetadata === null) {
|
if(fileMetadata === null) {
|
||||||
fileMetadata = {
|
fileMetadata = {
|
||||||
|
@ -635,6 +645,41 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pwsbox = document.getElementById("maxinput");
|
||||||
|
pwsbox.onchange = function(e) {
|
||||||
|
resetDisplay();
|
||||||
|
if(pwsbox.files.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
function decompressor(data) {
|
||||||
|
return (decodeLzari(data)).buffer;
|
||||||
|
}
|
||||||
|
GlobalState.fileReader.readAsArrayBuffer(pwsbox.files[0]);
|
||||||
|
GlobalState.fileReader.onloadend = function() {
|
||||||
|
GlobalState.fileReader.onloadend = void(0);
|
||||||
|
try {
|
||||||
|
let vFilesystem = readMaxPwsFile(GlobalState.fileReader.result, decompressor);
|
||||||
|
let output = readPS2D(vFilesystem[vFilesystem.rootDirectory]["icon.sys"].data);
|
||||||
|
updateDisplay(output);
|
||||||
|
let output2 = new Object();
|
||||||
|
Object.keys(output.filenames).forEach(function(file) {
|
||||||
|
output2[file] = readIconFile(vFilesystem[vFilesystem.rootDirectory][output.filenames[file]].data);
|
||||||
|
});
|
||||||
|
GlobalState.iconState.cachedIconSys = output;
|
||||||
|
GlobalState.iconState.currentSubmodel = 0;
|
||||||
|
GlobalState.iconState.source = output2;
|
||||||
|
GlobalState.iconState.currentIcon = output2.n;
|
||||||
|
renderIcon(output2.n, output);
|
||||||
|
console.info("model files (cbs)", output2);
|
||||||
|
console.info("icon.sys (cbs)", output);
|
||||||
|
} catch(e) {
|
||||||
|
if(glBgContext!==null){glBgContext.clear(glBgContext.COLOR_BUFFER_BIT);}
|
||||||
|
if(glFgContext!==null){glFgContext.clear(glFgContext.COLOR_BUFFER_BIT | glFgContext.DEPTH_BUFFER_BIT);}
|
||||||
|
console.error(e);
|
||||||
|
alert(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
function createShader(gl, type, source) {
|
function createShader(gl, type, source) {
|
||||||
let shader = gl.createShader(type);
|
let shader = gl.createShader(type);
|
||||||
gl.shaderSource(shader, source);
|
gl.shaderSource(shader, source);
|
||||||
|
@ -716,7 +761,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.7.0+u1";
|
document.getElementById("clientVersion").textContent = "0.8.0";
|
||||||
document.getElementById("currentYear").textContent = (new Date()).getFullYear().toString();
|
document.getElementById("currentYear").textContent = (new Date()).getFullYear().toString();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
19
index.js
19
index.js
|
@ -62,6 +62,22 @@ switch(processObj.argv[2]) {
|
||||||
console.log(output);
|
console.log(output);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "max":
|
||||||
|
case "pws": {
|
||||||
|
let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "file.max");
|
||||||
|
function myUnlzari(inputBuffer) {
|
||||||
|
return (require("./lzari.js").decodeLzari(inputBuffer)).buffer;
|
||||||
|
}
|
||||||
|
const parsed = iconjs.readMaxPwsFile(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength), myUnlzari);
|
||||||
|
console.log(parsed);
|
||||||
|
const PS2D = iconjs.readPS2D(parsed[parsed.rootDirectory]["icon.sys"].data);
|
||||||
|
let output = {parsed, PS2D}
|
||||||
|
Object.keys(PS2D.filenames).forEach(function(file) {
|
||||||
|
output[file] = iconjs.readIconFile(parsed[parsed.rootDirectory][PS2D.filenames[file]].data);
|
||||||
|
});
|
||||||
|
console.log(output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "sys": {
|
case "sys": {
|
||||||
let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "icon.sys");
|
let inputFile = filesystem.readFileSync(processObj.argv[3] ? processObj.argv[3] : "icon.sys");
|
||||||
const metadata = iconjs.readPS2D(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength));
|
const metadata = iconjs.readPS2D(inputFile.buffer.slice(inputFile.byteOffset, inputFile.byteOffset + inputFile.byteLength));
|
||||||
|
@ -70,7 +86,6 @@ switch(processObj.argv[2]) {
|
||||||
Object.keys(metadata.filenames).forEach(function(file) {
|
Object.keys(metadata.filenames).forEach(function(file) {
|
||||||
let getFile = filesystem.readFileSync(metadata.filenames[file]);
|
let getFile = filesystem.readFileSync(metadata.filenames[file]);
|
||||||
const output = iconjs.readIconFile(getFile.buffer.slice(getFile.byteOffset, getFile.byteOffset + getFile.byteLength));
|
const output = iconjs.readIconFile(getFile.buffer.slice(getFile.byteOffset, getFile.byteOffset + getFile.byteLength));
|
||||||
//console.log(individialIcon);
|
|
||||||
console.log(`contents of ${metadata.filenames[file]} (${file}):`, output, "\n");
|
console.log(`contents of ${metadata.filenames[file]} (${file}):`, output, "\n");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -91,6 +106,8 @@ psv: Read a PS3 export file.
|
||||||
sps: Read a SharkPort export file.
|
sps: Read a SharkPort export file.
|
||||||
xps: Read a X-Port export file.
|
xps: Read a X-Port export file.
|
||||||
cbs: Read a CodeBreaker Save export file.
|
cbs: Read a CodeBreaker Save export file.
|
||||||
|
max: Read a Max Drive export file.
|
||||||
|
pws: Read a PowerSave export file.
|
||||||
|
|
||||||
sys: Read a icon.sys (964 bytes) file, and attempt
|
sys: Read a icon.sys (964 bytes) file, and attempt
|
||||||
to read icon files from the current directory.
|
to read icon files from the current directory.
|
||||||
|
|
Loading…
Reference in New Issue