mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 15:09:05 +00:00
130 lines
3.7 KiB
JavaScript
130 lines
3.7 KiB
JavaScript
import { spawnSync } from "child_process";
|
|
import { readFileSync, mkdirSync, writeFileSync } from "fs";
|
|
import { join, resolve } from "path";
|
|
import KaitaiStream from "kaitai-struct/KaitaiStream.js";
|
|
import Lapk from "./Lapk.js";
|
|
|
|
export function extract_lapks(tempdir, jpsxdec_jar) {
|
|
spawnSync(
|
|
"java",
|
|
[
|
|
"-jar",
|
|
jpsxdec_jar,
|
|
"-x",
|
|
join(tempdir, "disc1.idx"),
|
|
"-i",
|
|
"LAPKS.BIN",
|
|
"-dir",
|
|
tempdir,
|
|
],
|
|
{ stdio: "inherit" }
|
|
);
|
|
const lapk_info = JSON.parse(readFileSync("lapks.json"));
|
|
|
|
let lapk_data = readFileSync(join(tempdir, "LAPKS.BIN"));
|
|
let output_folder = join("..", "..", "src", "static", "sprites", "lain");
|
|
|
|
mkdirSync(output_folder, { recursive: true });
|
|
|
|
for (let [index, lapk_entry] of lapk_info.entries()) {
|
|
let data = lapk_data.slice(
|
|
lapk_entry.offset,
|
|
lapk_entry.offset + lapk_entry.size
|
|
);
|
|
let parsed_lapk = new Lapk(new KaitaiStream(data));
|
|
let images = [];
|
|
if (index != 37) continue;
|
|
|
|
for (let [frame_number, cell_data] of parsed_lapk.data.cellData.entries()) {
|
|
const cell_header = parsed_lapk.data.cellHeaders[frame_number];
|
|
// create bitstream header (from https://github.com/m35/jpsxdec/blob/1de0518583236844b93f5fcc8a4d330a01c222b3/laintools/src/laintools/Lain_LAPKS.java#L319)
|
|
let bitstream_header = Buffer.alloc(8);
|
|
bitstream_header.writeInt8(cell_data.chrominanceQuantisationScale);
|
|
bitstream_header.writeInt8(cell_data.luminanceQuantisationScale, 1);
|
|
bitstream_header.writeInt16LE(0x3800, 2);
|
|
bitstream_header.writeInt16LE(cell_data.runLengthCodeCount, 4);
|
|
bitstream_header.writeInt16LE(0x0000, 6);
|
|
let output_bitstream = Buffer.concat(
|
|
[bitstream_header, cell_data.imageData],
|
|
cell_data.imageDataSize + 8
|
|
);
|
|
let bitstream_file = join(tempdir, `${index}_${frame_number}.bs`);
|
|
let out_frame = join(tempdir, `${index}_${frame_number}.png`);
|
|
let out_mask = join(tempdir, `${index}_${frame_number}_mask.gray`);
|
|
let out_alpha = join(tempdir, `${index}_${frame_number}_alpha.png`);
|
|
writeFileSync(bitstream_file, output_bitstream);
|
|
writeFileSync(out_mask, Buffer.from(cell_data.bitMask));
|
|
spawnSync(
|
|
"java",
|
|
[
|
|
"-jar",
|
|
jpsxdec_jar,
|
|
"-f",
|
|
resolve(bitstream_file),
|
|
"-static",
|
|
"bs",
|
|
"-dim",
|
|
`${cell_data.width}x${cell_data.height}`,
|
|
"-up",
|
|
"Lanczos3",
|
|
],
|
|
{ stdio: "inherit", cwd: tempdir }
|
|
);
|
|
spawnSync(
|
|
"convert",
|
|
[
|
|
"-background",
|
|
"none",
|
|
"(",
|
|
"-extent",
|
|
"352x367",
|
|
"xc:none",
|
|
")",
|
|
"(",
|
|
out_frame,
|
|
"(",
|
|
"-depth",
|
|
"2",
|
|
"-size",
|
|
`${cell_data.width}x${cell_data.height}`,
|
|
out_mask,
|
|
"-alpha",
|
|
"off",
|
|
")",
|
|
"-compose",
|
|
"copy-opacity",
|
|
"-composite",
|
|
")",
|
|
"-geometry",
|
|
`+${320 / 2 + 4 - cell_header.negativeXPosition}+${
|
|
352 - 1 - cell_header.negativeYPosition
|
|
}`,
|
|
"-compose",
|
|
"over",
|
|
"-composite",
|
|
out_alpha,
|
|
],
|
|
{ stdio: "inherit" }
|
|
);
|
|
images.push(out_alpha);
|
|
}
|
|
|
|
if (lapk_entry.tile != "") {
|
|
spawnSync(
|
|
"montage",
|
|
[
|
|
"-background",
|
|
"none",
|
|
"-tile",
|
|
lapk_entry.tile,
|
|
"-geometry",
|
|
"+0+0",
|
|
...images,
|
|
join(output_folder, lapk_entry.output_name)
|
|
],
|
|
{ stdio: "inherit" }
|
|
);
|
|
|
|
}
|
|
}
|
|
}
|