CSF File Format
From ModEnc
CSF files hold stringtables for RA2/YR (also for Generals/ZH and probably others).
For more information about what a CSF file is, go to the CSF page.
On this page you will find a guide to how the format is built up.
Contents |
[edit] The Header
The header of a CSF file is 0x18 bytes long.
It is built up like this:
| Offset | Type | Description |
|---|---|---|
| 0x0 | char[4] |
" FSC" |
| 0x4 | DWORD |
CSF Version |
| 0x8 | DWORD |
NumLabels |
| 0xC | DWORD |
NumExtraValues |
| 0x10 | DWORD |
(nothing) |
| 0x14 | DWORD |
Language |
[edit] Language
The language DWORD can have the following values (others will be recognized as "Unknown"):
0 = US (English)* 1 = UK (English) 2 = German* 3 = French* 4 = Spanish 5 = Italian 6 = Japanese 7 = Jabberwockie 8 = Korean* 9 = Chinese* >9 = Unknown
* RA2/YR has been released in this language.
[edit] Labels
After the header, the label data follows.
A label can be considered an entry in the stringtable (e.g. "GUI:OK" is a label).
Each label can have a name (e.g. "NAME:MTNK"), a value (e.g. "Grizzly Tank") and an extra value (no example in the original ra2.csf/ra2md.csf).
While the name and the extra value are ASCII strings, the value is a Unicode string (in order to support Korean, Chinese, etc).
Now let's come to how the data is stored in the CSF file:
[edit] Label header
The label data begins with a label header, which is built up like this:
| Offset | Type | Description |
|---|---|---|
| 0x0 | char[4] |
" LBL" |
| 0x4 | DWORD |
Number of sub-strings |
| 0x8 | DWORD |
LabelNameLength |
| 0xC | char[LabelNameLength] |
LabelName |
The first label in ra2md.csf can be found at 0x18.
Note: Spaces, tabs and line breaks will be formatted out of the label's name, therefore they cannot be used.
[edit] Values
Directly after the label header, the value data follows.
This is how it is built up:
| Offset | Type | Description |
|---|---|---|
| 0x0 | char[4] |
" RTS or "WRTS" |
| 0x4 | DWORD |
ValueLength |
| 0x8 | byte[ValueLength*2] |
Value |
| 0x8+ValueLength*2 | DWORD |
ExtraValueLength |
| 0x8+ValueLength*2+0x4 | char[ExtraValueLength] |
ExtraValue |
[edit] Decoding the value
To decode the value to a Unicode string, not every byte of the value data (or substract it from 0xFF).
An example in C++:
int ValueDataLength = ValueLength << 1
for(int i = 0; i < ValueDataLen;i++)
{
ValueData[i]=~ValueData[i]
}

