You've already forked PrimeRemasterStructs
mirror of
https://github.com/PrimeDecomp/PrimeRemasterStructs.git
synced 2026-03-31 14:23:23 -07:00
199 lines
5.4 KiB
Plaintext
199 lines
5.4 KiB
Plaintext
#ifndef _MESSAGESTUDIOBINARYTEXT
|
|
#define _MESSAGESTUDIOBINARYTEXT
|
|
|
|
struct MSBTHeader {
|
|
char magic[8];
|
|
Assert(magic == "MsgStdBn");
|
|
ushort bom <format=hex>;
|
|
//Assert(bom == 0xFEFF); // Big-Endian byte order
|
|
//Let's check
|
|
if (bom == 0xFFFE && isDKCTF)
|
|
{
|
|
LittleEndian();
|
|
}
|
|
ushort unk1;
|
|
ubyte maybeMajorVersion;
|
|
ubyte maybeMinorVersion;
|
|
ushort sectionCount;
|
|
ushort unk3;
|
|
uint fileSize;
|
|
byte padding[10]<hidden=true>;
|
|
};
|
|
|
|
struct TableHeader(string expectedMagic) {
|
|
char magic[4];
|
|
Assert(magic == expectedMagic);
|
|
uint tableSize;
|
|
byte padding[8]<hidden=true>;
|
|
};
|
|
|
|
struct LabelOffset {
|
|
uint stringCount;
|
|
uint stringOffset;
|
|
};
|
|
|
|
struct LabelEntry {
|
|
ubyte stringLength;
|
|
char str[stringLength];
|
|
uint stringTableIndex;
|
|
};
|
|
|
|
wstring LabelEntryRead(LabelEntry &le) {
|
|
return le.str;
|
|
}
|
|
|
|
struct LabelsSection {
|
|
TableHeader header("LBL1");
|
|
local int64 tableStart = FTell();
|
|
uint offsetCount;
|
|
LabelOffset offset[offsetCount];
|
|
local uint i;
|
|
for (i = 0; i < offsetCount; i++) {
|
|
Assert(FTell() == tableStart + offset[i].stringOffset);
|
|
if (offset[i].stringCount) {
|
|
LabelEntry label[offset[i].stringCount]<optimize=false,read=LabelEntryRead>;
|
|
}
|
|
}
|
|
while (ReadUByte(FTell()) == 0xAB) {
|
|
byte padding<hidden=true>;
|
|
}
|
|
};
|
|
|
|
struct AttributeEntry {
|
|
wstring str;
|
|
};
|
|
|
|
wstring AttributeEntryRead(AttributeEntry &ae) {
|
|
return ae.str;
|
|
}
|
|
|
|
struct AttributesSection {
|
|
TableHeader header("ATR1");
|
|
local int64 tableStart = FTell();
|
|
uint offsetCount;
|
|
uint entrySize; // should always be 4
|
|
if (isDKCTF == 0)
|
|
{
|
|
uint offset[offsetCount];
|
|
local uint i;
|
|
for (i = 0; i < offsetCount; i++) {
|
|
Assert(FTell() == tableStart + offset[i]);
|
|
AttributeEntry attribute<optimize=false,read=AttributeEntryRead>;
|
|
}
|
|
}
|
|
while (ReadUByte(FTell()) == 0xAB) {
|
|
byte padding<hidden=true>;
|
|
}
|
|
};
|
|
|
|
struct TextsEntry(int64 size) {
|
|
wchar_t str[size / 2];
|
|
};
|
|
|
|
wstring TextsEntryRead(TextsEntry &te) {
|
|
local wstring out;
|
|
local uint i;
|
|
for (i = 0; i < (sizeof te.str / 2); i++) {
|
|
// MSBT includes "text commands" in strings, which are sections of binary
|
|
// data with varying lengths. Parsing them is complicated, so for now we
|
|
// just skip all characters below the printable range. Some random bytes
|
|
// will still slip through.
|
|
if (te.str[i] >= 0x20) {
|
|
out += te.str[i];
|
|
}
|
|
}
|
|
return out;
|
|
}
|
|
|
|
struct TextsSection {
|
|
TableHeader header("TXT2");
|
|
local int64 tableStart = FTell();
|
|
uint offsetCount;
|
|
uint offset[offsetCount];
|
|
local uint i;
|
|
// This is kind of hacky- these strings may contain null characters, so
|
|
// we need to read between the offsets and stop at the end of the table.
|
|
for (i = 0; i < offsetCount - 1; i++) {
|
|
TextsEntry text(offset[i + 1] - offset[i])<optimize=false,read=TextsEntryRead>;
|
|
}
|
|
TextsEntry text(header.tableSize - offset[i])<optimize=false,read=TextsEntryRead>;
|
|
|
|
while (ReadUByte(FTell()) == 0xAB) {
|
|
byte padding<hidden=true>;
|
|
}
|
|
};
|
|
|
|
struct Language (string expectedLanguage) {
|
|
ChunkDescriptor languageChunkHeader;
|
|
Assert(languageChunkHeader.id == expectedLanguage);
|
|
// Each section here is heavily referenced from https://zeldamods.org/wiki/Msbt
|
|
struct MSBTContents {
|
|
MSBTHeader header;
|
|
LabelsSection labels;
|
|
AttributesSection attributes;
|
|
TextsSection texts;
|
|
if (isDKCTF) //Swap back
|
|
{
|
|
BigEndian();
|
|
}
|
|
} contents;
|
|
};
|
|
|
|
struct TableName {
|
|
ChunkDescriptor tableNameChunkHeader;
|
|
Assert(tableNameChunkHeader.id == "TBNM");
|
|
CStringFixed name;
|
|
};
|
|
|
|
struct MessageStudioBinaryText(uint32 readerVersion, uint32 writerVersion)
|
|
{
|
|
Assert(readerVersion == writerVersion);
|
|
if (isDKCTF == 1)
|
|
{
|
|
Language us_english("USEN");
|
|
Language us_french("USFR");
|
|
Language us_spanish("USSP");
|
|
Language eu_english("EUEN");
|
|
Language eu_french("EUFR");
|
|
Language eu_spanish("EUSP");
|
|
Language eu_german("EUGE");
|
|
Language eu_italian("EUIT");
|
|
Language jp_japanese("JPJP");
|
|
} else if (readerVersion == 10) {
|
|
Language us_english("USEN");
|
|
Language eu_english("EUEN");
|
|
Language eu_french("EUFR");
|
|
Language us_french("USFR");
|
|
Language eu_spanish("EUSP");
|
|
Language eu_german("EUGE");
|
|
Language eu_italian("EUIT");
|
|
Language eu_dutch("EUDU");
|
|
Language jp_japanese("JPJP");
|
|
Language ko_korean("KOKO");
|
|
Language ch_traditionalchinese("CHTC");
|
|
Language ch_simplifiedchinese("CHSC");
|
|
Language us_spanish("USSP");
|
|
} else if (readerVersion == 16) {
|
|
Language us_english("USEN");
|
|
Language eu_english("EUEN");
|
|
Language us_portuguese("USPO");
|
|
Language eu_french("EUFR");
|
|
Language us_french("USFR");
|
|
Language eu_spanish("EUSP");
|
|
Language us_spanish("USSP");
|
|
Language eu_german("EUGE");
|
|
Language eu_italian("EUIT");
|
|
Language eu_dutch("EUDU");
|
|
Language jp_japanese("JPJP");
|
|
Language ch_simplifiedchinese("CHSC");
|
|
Language ko_korean("KOKO");
|
|
Language ch_traditionalchinese("CHTC");
|
|
TableName tableName;
|
|
} else {
|
|
Assert(false, "Unsupported MSBT version!");
|
|
}
|
|
};
|
|
|
|
|
|
#endif// _MESSAGESTUDIOBINARYTEXT
|