Story & Battle Dialog

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

Story & Battle Dialog

Post by NoahSteam » Wed Aug 29, 2018 3:44 am

Image

This is to document how the story sequences work. This covers how the text is stored, how the font is stored, and where the sequence of the dialog is stored.

Overview
Each story sequence is made up of four files.
1) #.BIN
2) #FCE.BIN
3) #KNJ.BIN
4) #TBL.BIN

Where # is a 4 digit number. Example: 0100.BIN, 0100FCE.BIN, 0100KNJ.BIN, 0100TBL.BIN. There are 56 sets of these. They can be found within SAKURA1 directory.

Each battle dialog sequence is made up of multiple files as well. The only ones needed to extract/insert text are the following:
1)M#MES.BIN
2)M#MES.FNT

Where # is a two digit number. Example: M01MES.BIN, M02MES.BIN, etc.. There are 13 of these in total. These are in the SAKURA2 directory.

Font Sheets - KNJ.BIN & MES.FNT files
0100KNJ (click to expand):
Image

Each story sequence has its own font sheet consisting of several hundred characters. The font sheets are stored inside of the KNJ files (MES.FNT for battle sequences). These files have no header data. They simply contain uncompressed 4bit 16x16 tiled images. 255 tiles per row and a max of 3 rows. So to extract them, you just keep reading (16*16)/2 bytes until the end of the file.

The palette for these images lives in a bunch of different files. I'm not exactly sure which of those files in particular is used to provide the palette for the images in KNJ files, so I just patch all of them with the palette of my own font sheet. The palettes are 32 bytes containing 16 colors in 16bit BGR format (5:5:5) where the highest bit is ignored (the Saturn processors are big-endian by the way).

Lines of Dialog - TBL & MES.BIN files
Image

TBL Header
Lines of dialog are stored in the TBL files (MES.FNT for battle sequences). The top of each of these files begins with a header. The first two bytes of the header specify the offset at which the lines of dialog start. The offset must be multiplied by 2 get the actual offset. For example 0100TBL begins with 04BC. This means that at 0x978 (0x4BC* 2) the first line of dialog starts.

The second two bytes specify the offset at which the dialog lines end. Again, this offset must be multiplied by two.

So to recap, here are the first 4 bytes:

Code: Select all

struct
{
     unsigned short offsetToDialog;       //mupltiply by 2 to get actual offset
     unsigned short offsetToDialogEnd;  //mupltiply by 2 to get actual offset
}
Immediately following these 4 bytes, we have information about each line of dialog in the file. Here is the format for each entry:

Code: Select all

struct
{
     unsigned short stringId; //An id that is used by other files to reference this line of dialog
     unsigned short offsetFromPrevString;  //Number of bytes the previous string was
} 
Format for Each Line of Dialog
Lines of dialog aren't stored as raw ascii, jis, or any other type of encoded text. Rather, each character of a line is represented by a 2 byte lookup into the font sheet found in the accompanying KNJ file. The lookup column is 1 based and not 0 based. So to reference the first character in the font sheet, the TBL file will say: 00 01. 00 means the 1st row and 01 means the first column. If the bytes are 0204, that means it is the character in the 3rd row and the 4th column.

Every line begins with 4 bytes of 0s. Every line ends with two bytes of 0s. However if the stringId of the line of dialog is C531, it will have some unique starting byte instead of 0000. Every line after the line with id C351 will have a an extra 4 bytes of data before the line data begins. I'm not sure what these 4 bytes signify. When patching, I preserve these values.

Sequence Files: #.BIN
Sequence files contain the sequence in which the strings are displayed along with which character's face image is associated with each string, commands to change background images, play sounds, etc. after a line of dialog. For my purposes, I only cared about the sequence ordering and the character's face image.

Dialog sequence info is preceded by the bytes 2280 or 2E80 if it is a LIPS line. Right after that are 2 bytes which refer the the stringId in the TBL file. To find the image associated with this line of dialog, we have to search backwards from the 2280 to find the first occurrence of 2B80??## where ## is a non-zero number. That number refers to an image in the FCE.BIN file. For an explanation of how FCE files work, refer to viewtopic.php?f=4&t=8.

There will only be an instance of an image id (2B8000##) when the image is going to change. For example, the first line of dialog has the the image 0169 associated with it. So before the 2280, we will encounter 2B8000169. The next 4 lines of dialog use the same image so they won't specify the image again. Before the 5th line of dialog another instance of the 2B80 identifier appear meaning that this will now be the character image.

Note: Sequencing of the dialog for battle sequences is much more complicated because the sequencing is stored in script files that appear to have executable code. This lives within FACE files in the SAKURA2 directory. I will cover how this data is stored later.

Post Reply