FACE Files

Discussion of the technical aspects of patching Sakura Taisen.
Post Reply
User avatar
NoahSteam
Site Admin
Posts: 55
Joined: Mon Jun 18, 2018 11:16 pm

FACE Files

Post by NoahSteam » Sat Aug 18, 2018 6:13 am

This is to document how FACE files work. FACE files can be found in the SAKURA2 directory. There are 14 of these files in total. FACE01.BIN, FACE02.BIN, etc..

Uses:
FACE files contain the face images of characters who will be speaking during the battle story dialog. In order to have the face of the speaker appear next to each line of dialog in the translation sheets, I needed to extract these. Also, once I realized that these images are compressed, I figured I might as well just go ahead and figure out how to decompress the compressed images in this game because that has to be done for menu and subtitle images anyways.
Image

Format:
Unlike the FCE files, FACE files are a bit complicated. It took me quite a while to figure out what the heck was going on in these files. So lets break it down.

-Header-
All of these files start with a header at the top. The header contains entries that specify where each of the face images lives in the file. Here are how the entries are specified:

Code: Select all

struct
{
    unsigned long offsetToData;
    unsigned long unknown;
}
Image data starts right after the header, therefore the size of the header can be determined by just looking at the offsetToData of the very first image.
For example FACE01.bin starts like this:
00 00 01 D8

This means that the first image is at an offset of 0x01D8.

-Image Header-
Image data starts with a a header of 16 bytes. What do all of these 16bytes specify? I'm not sure. The important thing is that 10 bytes into the header is a 2 byte offset to the palette of this image. So to get to the palette, you have to go to byte offsetToData + paletteOffset. Every image in the file has its own palette and this palette appears directly after the image data. There is no way of knowing where the image data ends though, which is why the paletteOffset is explicitly specified.

-Image Data-
The image data itself is compressed. This was the hardest part to figure out. It turns out that Sakura Taisen uses the PRS compression method which is used by several Sega Saturn games. For more info on PRS compression, refer to following pages:
https://segaretro.org/PRS_compression
https://github.com/Sylverant/pso_tools/ ... er/prstool

Once the data has been uncompressed, the are 64 bytes at the start which appear to make another header of some sort. I don't know what these bytes specify but for the purposes of this translation project, they don't matter. What matters are the remaining bytes. These are the uncompressed bytes of image data. The image will be a an 8bpp image. The full size of the image is 40x80. The first 40x48 pixels are the face and then there are two more 40x20 images that are the eyes opening and closing. Here is the first image from FACE01:
Image

-Palette Data-
As mentioned above, every image within the file has its own palette. The offset to the palette is 10 bytes into the the header of each image. The palettes contain 128 colors in BGR format and the bgr values are packed into 15bits BGR(5:5:5) format. So basically you have to take every two bytes and & them with 0x7fff. Also it means that the bytes in the actual image data have to be and'ed by 0x7f because the palette only contains 128 entries, so the first bit of each palette entry byte is ignored.

Interestingly, the images only ever use 64 colors of that 128 color palette. I wonder why they didn't just use a 64 color palette instead because the Saturn does in fact support 64 color images.

Post Reply