Closed kion-dgl closed 2 months ago
In order to encode this, we'll need to break down PL00T.BIN
.
we can start with the body image. The header for the body image starts at 0x00
and ends at 0x30
. Which is followed by the compressed texture which is made up of the bitfield and payload.
The bitfield has a length of 0x270
and the payloads ends on 0x2998
, which means it has a length of about 0x26F8
.
The full size of the body texture is 0x8080
bytes. 0x80
for the palette and 0x8000
for the indexed 256x256 width and height. The full length of the file is 0x7000. Which means that we can't fit even a single uncompressed texture in the file.
What this means is that we need to use compression, but we can't be too good at it. The second palette starts at 0x3000
and the game reads archives at offsets of 0x800. What this means is that if our compression ends before 0x2800, the game will not seek to 0x3000
for the next palette and soft crash.
What this means is that there's a possibility to add more information into the game if we really got creative. But for now our goal is to replace what's existing with something else as close a possible to reduce the number of potential problems we can have just getting "hello world" up and running.
In practicality what that means is that we take miku/body-1.png
, we get the palette, we get the indexed image, and then we compress that to somewhere between 0x2800 and 0x3000 in length, and then we patch that into the game file before searching and replacing it.
Well, I managed to encode something without breaking the game. But the broken palette is breaking my heart. Looks like we have to add another test case for eating our own dog food.
Fixed:
Problem was that I wasn't adding in the blue color correctly. Here's the fixed code to go from rgba8888 to argb1555.
const encodeTexel = (r: number, g: number, b: number, a: number) => {
const rClr = Math.floor((r >> 3) & 0xff);
const gClr = Math.floor((g >> 3) & 0xff);
const bClr = Math.floor((b >> 3) & 0xff);
const aClr = a === 0 ? 0 : 0x8000;
const texel = rClr | (gClr << 5) | (bClr << 10) | aClr;
return texel;
};
Which means I can switch attention to the face. For this one, I will need to slice off the second half of the encoded image to replace with the special weapons, until i come back later to implement special weapons.
But realistically with special weapons, the content is going to be the same and then I will need to implement a look up to get the correct order for the textures.
I think the first encoding we want to start with is the textures. Hopefully if we get this right, we wont need to change it until we come back to bash our head in with updating special weapons.