kion-dgl / Miku-Legends-2

Source Code for Writing files to the Megaman Legends 2 format to replace Megaman with Miku
GNU General Public License v3.0
3 stars 0 forks source link

Encode Textures to Replace in Game #14

Closed kion-dgl closed 2 months ago

kion-dgl commented 2 months ago

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.

kion-dgl commented 2 months ago

PL00T.BIN

In order to encode this, we'll need to break down PL00T.BIN.

Body

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.

Compression

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.

kion-dgl commented 2 months ago

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.

Screenshot from 2024-07-16 11-19-51

Fixed:

image

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;
};
kion-dgl commented 2 months ago

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.