Skip to content

Commit

Permalink
Merge pull request #72 from kion-dgl/68-update-dashie-in-the-flutter
Browse files Browse the repository at this point in the history
68 update dashie in the flutter
  • Loading branch information
kion-dgl authored Oct 1, 2024
2 parents 6ee0f97 + 5de402f commit c53ee7c
Show file tree
Hide file tree
Showing 9 changed files with 595 additions and 99 deletions.
Binary file added bin/flutter-ST06T.BIN
Binary file not shown.
10 changes: 9 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
} from "./src/EncodeWeapon";
import { updateDemoLogo } from "./src/GAME";
import { updateFlutterPaintings } from "./src/ST05T";
import { updateFlutterPaintings2 } from "./src/ST06T";
import { updateYosyonkePaintings } from "./src/ST47T";
import { updateYosyonkePaintings2 } from "./src/ST0AT";
import { updateYosyonkePaintings3 } from "./src/ST0CT";
Expand Down Expand Up @@ -217,7 +218,11 @@ replaceDrillArm("miku/weapons/PL00R10_001.obj");
**/

encodeApronMegaman();
updateST03T("miku/apron/body-01.png", "miku/faces/ST03T.png");
updateST03T(
"miku/apron/body-01.png",
"miku/faces/ST03T.png",
"miku/paintings/dashie2.png",
);
updateSceneModel();
updateDemoLogo("miku/title-smol.png");

Expand All @@ -226,6 +231,9 @@ updateFlutterPaintings(
"miku/paintings/roll-room.png",
"miku/paintings/roll-lofi.png",
);

updateFlutterPaintings2("miku/paintings/dashie2.png");

updateYosyonkePaintings(
"miku/paintings/room-203.png",
"miku/paintings/room-203-poster.png",
Expand Down
Binary file added miku/paintings/dashie.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added miku/paintings/dashie2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/EncodeRom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ const encodeRom = () => {
"cut-ST2501.BIN",
"GAME.BIN",
"flutter-ST05T.BIN",
"flutter-ST06T.BIN",
"yosyonke-ST47T.BIN",
"yosyonke-ST0AT.BIN",
"yosyonke-ST0CT.BIN",
Expand Down
39 changes: 39 additions & 0 deletions src/ST0305.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,44 @@ const CUT_SCENES = [
},
];

const updateDashie = (bin: Buffer, pngPath: string) => {
const pngData = readFileSync(pngPath);

const imgOfs = 0x1a000;
const pal: number[] = [];

const encodedLogo = encodeCutSceneTexture(pal, pngData);
const encodedTexture = Buffer.from(bin.subarray(0x1a800, 0x22800));

// Update Palette
const palOfs = 0x23800;
const red = encodeTexel(255, 0, 0, 255);
for (let i = 0; i < pal.length; i++) {
bin.writeUInt16LE(pal[i], palOfs + 0x30 + i * 2);
// bin.writeUInt16LE(red, palOfs + 0x30 + i * 2);
}

const ROW_LEN = 0x80;
const X_START = 0;
const Y_START = 88;
let texOfs = ROW_LEN * Y_START; // + PAL_OFS;
let logoOfs = 0;
const HEIGHT = 40;
const WIDTH = 64;
for (let y = 0; y < HEIGHT; y++) {
texOfs += X_START / 2;
for (let x = 0; x < WIDTH / 2; x++) {
encodedTexture[texOfs++] = encodedLogo[logoOfs++];
}
texOfs += (256 - X_START - WIDTH) / 2;
}

let ofs = 0x1a800;
for (let i = 0; i < encodedTexture.length; i++) {
bin[ofs + i] = encodedTexture[i];
}
};

const encodeCutScenes = () => {
const palette: number[] = [];

Expand Down Expand Up @@ -535,6 +573,7 @@ const fixEggs = (buffer: Buffer) => {
const encodeApronMegaman = () => {
encodeCutScenes();
const file = readFileSync("out/cut-ST0305.BIN");
updateDashie(file, "miku/paintings/dashie2.png");
const contentEnd = file.readUInt32LE(0x04);
const buffer = file.subarray(0x30, 0xe000);

Expand Down
178 changes: 177 additions & 1 deletion src/ST03T.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,97 @@ import {
readPixel,
} from "./EncodeTexture";

const decompress = (src: Buffer) => {
const tim = {
type: src.readUInt32LE(0x00),
fullSize: src.readUInt32LE(0x04),
paletteX: src.readUInt16LE(0x0c),
paletteY: src.readUInt16LE(0x0e),
colorCount: src.readUInt16LE(0x10),
paletteCount: src.readUInt16LE(0x12),
imageX: src.readUInt16LE(0x14),
imageY: src.readUInt16LE(0x16),
width: src.readUInt16LE(0x18),
height: src.readUInt16LE(0x1a),
bitfieldSize: src.readUInt16LE(0x24),
payloadSize: src.readUInt16LE(0x26),
};

switch (tim.colorCount) {
case 16:
tim.width *= 4;
break;
case 256:
tim.width *= 2;
break;
default:
tim.paletteCount *= tim.colorCount / 16;
tim.colorCount = 16;
tim.width *= 4;
break;
}

const { fullSize, bitfieldSize } = tim;
const bitfield: number[] = new Array();
const target = Buffer.alloc(fullSize);

// Read Bitfield

const bitfieldBuffer = src.subarray(0x30, 0x30 + bitfieldSize);
let ofs = 0x30;
for (let i = 0; i < bitfieldSize; i += 4) {
const dword = src.readUInt32LE(ofs + i);
for (let k = 31; k > -1; k--) {
bitfield.push(dword & (1 << k) ? 1 : 0);
}
}

ofs += bitfieldSize;
const payloadStart = 0;

// Decompress

let outOfs = 0;
let windowOfs = 0;
let cmdCount = 0;
let bytes = 0;

for (let i = 0; i < bitfield.length; i++) {
const bit = bitfield[i];
if (outOfs === fullSize) {
const payload = src.subarray(0x30 + bitfieldSize, ofs);
break;
}

const word = src.readUInt16LE(ofs);
ofs += 2;

switch (bit) {
case 0:
target.writeUInt16LE(word, outOfs);
outOfs += 2;
break;
case 1:
if (word === 0xffff) {
windowOfs += 0x2000;
cmdCount = 0;
bytes = 0;
} else {
cmdCount++;
const copyFrom = windowOfs + ((word >> 3) & 0x1fff);
const copyLen = ((word & 0x07) + 2) * 2;
bytes += copyLen;
for (let i = 0; i < copyLen; i++) {
target[outOfs++] = target[copyFrom + i];
}
}
break;
}
}

return target;
};

/**
* Updates the face texture in the prodived archive
* @param src Buffer of the bin file to be updated
Expand Down Expand Up @@ -393,12 +484,96 @@ const updateEggs = (src: Buffer) => {
// }
};

const updateDashie = (bin: Buffer, pngPath: string) => {
const pngData = readFileSync(pngPath);

const imgOfs = 0x2e000;
const pal: number[] = [];

const encodedLogo = encodeCutSceneTexture(pal, pngData);
const mpTexture = decompress(Buffer.from(bin.subarray(imgOfs)));

const includedPal = Buffer.from(mpTexture.subarray(0, 0x20));
const encodedTexture = Buffer.from(mpTexture.subarray(0x20));

// Update Palette
const palOfs = 0x33800;
const red = encodeTexel(255, 0, 0, 255);
for (let i = 0; i < pal.length; i++) {
bin.writeUInt16LE(pal[i], palOfs + 0x30 + i * 2);
// bin.writeUInt16LE(red, palOfs + 0x30 + i * 2);
}

const ROW_LEN = 0x80;
const X_START = 0;
const Y_START = 88;
let texOfs = ROW_LEN * Y_START; // + PAL_OFS;
let logoOfs = 0;
const HEIGHT = 40;
const WIDTH = 64;
for (let y = 0; y < HEIGHT; y++) {
texOfs += X_START / 2;
for (let x = 0; x < WIDTH / 2; x++) {
encodedTexture[texOfs++] = encodedLogo[logoOfs++];
}
texOfs += (256 - X_START - WIDTH) / 2;
}

// console.log("Logo Pos: 0x%s", logoOfs.toString(16));

const imageData: number[] = new Array();
for (let ofs = 0; ofs < encodedTexture.length; ofs++) {
const byte = encodedTexture.readUInt8(ofs);

imageData.push(byte & 0xf);
imageData.push(byte >> 4);
}

const [bodyBitField, compressedBody] = compressNewTexture(
includedPal,
encodedTexture,
1,
);
const len = bodyBitField.length + compressedBody.length;

for (let i = 0x2e030; i < 0x321b0; i++) {
bin[i] = 0;
}

let ofs = 0x2e030;
for (let i = 0; i < bodyBitField.length; i++) {
bin[ofs++] = bodyBitField[i];
}

for (let i = 0; i < compressedBody.length; i++) {
bin[ofs++] = compressedBody[i];
}

if (ofs <= 0x32000) {
console.log("too short!!!");
throw new Error("dashie painting too short");
} else if (len > 0x32800) {
console.log("too long");
throw new Error("dashie painting too long");
} else {
console.log("yaya!!!");
}

console.log("End: 0x%s", ofs.toString(16));
bin.writeInt16LE(bodyBitField.length, 0x2e024);
};

/**
* Takes a face texture and a body texture to replace in the opening cut scene
* @param bodyTexture relative path to png file for body texture
* @param faceTexture relative path to png file for face texture
* @param dashie relative path to png file for painting in flutter living room
*/
const updateST03T = (bodyTexture: string, faceTexture: string) => {
const updateST03T = (
bodyTexture: string,
faceTexture: string,
dashie: string,
) => {
// Read the input files
const src = readFileSync("bin/cut-ST03T.BIN");
const body = readFileSync(bodyTexture);
Expand All @@ -409,6 +584,7 @@ const updateST03T = (bodyTexture: string, faceTexture: string) => {
updateFace(src, face);
// updateEggs(src);

updateDashie(src, dashie);
// Write the resulting Archive
writeFileSync("out/cut-ST03T.BIN", src);
};
Expand Down
Loading

0 comments on commit c53ee7c

Please sign in to comment.