Rewrote CStringTable (currently doesn't compile)
This commit is contained in:
parent
02e4e47fb2
commit
e92a9fc6b0
|
@ -1 +1 @@
|
||||||
Subproject commit 47d83075e0fb20786ad28c2e945a204ed1837856
|
Subproject commit 6557c54f799c3bbb16900d2d98a75e9533a6f80d
|
|
@ -110,6 +110,7 @@ HEADERS += \
|
||||||
Resource/Script/CScriptObject.h \
|
Resource/Script/CScriptObject.h \
|
||||||
Resource/Script/CScriptTemplate.h \
|
Resource/Script/CScriptTemplate.h \
|
||||||
Resource/Script/EVolumeShape.h \
|
Resource/Script/EVolumeShape.h \
|
||||||
|
Resource/StringTable/CStringTable.h \
|
||||||
Resource/CCollisionMesh.h \
|
Resource/CCollisionMesh.h \
|
||||||
Resource/CCollisionMeshGroup.h \
|
Resource/CCollisionMeshGroup.h \
|
||||||
Resource/CFont.h \
|
Resource/CFont.h \
|
||||||
|
@ -119,7 +120,6 @@ HEADERS += \
|
||||||
Resource/CMaterialSet.h \
|
Resource/CMaterialSet.h \
|
||||||
Resource/CResource.h \
|
Resource/CResource.h \
|
||||||
Resource/CScan.h \
|
Resource/CScan.h \
|
||||||
Resource/CStringTable.h \
|
|
||||||
Resource/CTexture.h \
|
Resource/CTexture.h \
|
||||||
Resource/CWorld.h \
|
Resource/CWorld.h \
|
||||||
Resource/EResType.h \
|
Resource/EResType.h \
|
||||||
|
@ -247,7 +247,8 @@ HEADERS += \
|
||||||
Resource/Script/Property/CGuidProperty.h \
|
Resource/Script/Property/CGuidProperty.h \
|
||||||
Resource/Script/CGameTemplate.h \
|
Resource/Script/CGameTemplate.h \
|
||||||
Resource/Script/NPropertyMap.h \
|
Resource/Script/NPropertyMap.h \
|
||||||
Resource/Script/NGameList.h
|
Resource/Script/NGameList.h \
|
||||||
|
Resource/StringTable/ELanguage.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -358,7 +359,8 @@ SOURCES += \
|
||||||
Resource/Script/Property/CFlagsProperty.cpp \
|
Resource/Script/Property/CFlagsProperty.cpp \
|
||||||
Resource/Script/CGameTemplate.cpp \
|
Resource/Script/CGameTemplate.cpp \
|
||||||
Resource/Script/NPropertyMap.cpp \
|
Resource/Script/NPropertyMap.cpp \
|
||||||
Resource/Script/NGameList.cpp
|
Resource/Script/NGameList.cpp \
|
||||||
|
Resource/StringTable/CStringTable.cpp
|
||||||
|
|
||||||
# Codegen
|
# Codegen
|
||||||
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
CODEGEN_DIR = $$EXTERNALS_DIR/CodeGen
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
#define CSCAN_H
|
#define CSCAN_H
|
||||||
|
|
||||||
#include "CResource.h"
|
#include "CResource.h"
|
||||||
#include "CStringTable.h"
|
|
||||||
#include "TResPtr.h"
|
#include "TResPtr.h"
|
||||||
#include "Core/Resource/Animation/CAnimationParameters.h"
|
#include "Core/Resource/Animation/CAnimationParameters.h"
|
||||||
|
#include "Core/Resource/StringTable/CStringTable.h"
|
||||||
#include <Common/EGame.h>
|
#include <Common/EGame.h>
|
||||||
|
|
||||||
class CScan : public CResource
|
class CScan : public CResource
|
||||||
|
|
|
@ -1,180 +0,0 @@
|
||||||
#ifndef CSTRINGTABLE_H
|
|
||||||
#define CSTRINGTABLE_H
|
|
||||||
|
|
||||||
#include "CResource.h"
|
|
||||||
#include <Common/BasicTypes.h>
|
|
||||||
#include <Common/CFourCC.h>
|
|
||||||
#include <Common/TString.h>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class CStringTable : public CResource
|
|
||||||
{
|
|
||||||
DECLARE_RESOURCE_TYPE(StringTable)
|
|
||||||
friend class CStringLoader;
|
|
||||||
|
|
||||||
std::vector<TString> mStringNames;
|
|
||||||
uint32 mNumStrings;
|
|
||||||
|
|
||||||
struct SLangTable
|
|
||||||
{
|
|
||||||
CFourCC Language;
|
|
||||||
std::vector<TString> Strings;
|
|
||||||
};
|
|
||||||
std::vector<SLangTable> mLangTables;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CStringTable(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
|
||||||
|
|
||||||
inline uint32 NumStrings() const { return mNumStrings; }
|
|
||||||
inline uint32 NumLanguages() const { return mLangTables.size(); }
|
|
||||||
inline CFourCC LanguageTag(uint32 Index) const { return mLangTables[Index].Language; }
|
|
||||||
inline TString String(uint32 LangIndex, uint32 StringIndex) const { return mLangTables[LangIndex].Strings[StringIndex]; }
|
|
||||||
inline TString StringName(uint32 StringIndex) const { return mStringNames[StringIndex]; }
|
|
||||||
|
|
||||||
TString String(CFourCC Lang, uint32 StringIndex) const
|
|
||||||
{
|
|
||||||
for (uint32 iLang = 0; iLang < NumLanguages(); iLang++)
|
|
||||||
{
|
|
||||||
if (LanguageTag(iLang) == Lang)
|
|
||||||
return String(iLang, StringIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
return TString();
|
|
||||||
}
|
|
||||||
|
|
||||||
CDependencyTree* BuildDependencyTree() const
|
|
||||||
{
|
|
||||||
// STRGs can reference FONTs with the &font=; formatting tag and TXTRs with the &image=; tag
|
|
||||||
CDependencyTree *pTree = new CDependencyTree();
|
|
||||||
EIDLength IDLength = (Game() <= EGame::Echoes ? k32Bit : k64Bit);
|
|
||||||
|
|
||||||
for (uint32 iLang = 0; iLang < mLangTables.size(); iLang++)
|
|
||||||
{
|
|
||||||
const SLangTable& rkTable = mLangTables[iLang];
|
|
||||||
|
|
||||||
for (uint32 iStr = 0; iStr < rkTable.Strings.size(); iStr++)
|
|
||||||
{
|
|
||||||
const TString& rkStr = rkTable.Strings[iStr];
|
|
||||||
|
|
||||||
for (uint32 TagIdx = rkStr.IndexOf('&'); TagIdx != -1; TagIdx = rkStr.IndexOf('&', TagIdx + 1))
|
|
||||||
{
|
|
||||||
// Check for double ampersand (escape character in DKCR, not sure about other games)
|
|
||||||
if (rkStr.At(TagIdx + 1) == '&')
|
|
||||||
{
|
|
||||||
TagIdx++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get tag name and parameters
|
|
||||||
uint32 NameEnd = rkStr.IndexOf('=', TagIdx);
|
|
||||||
uint32 TagEnd = rkStr.IndexOf(';', TagIdx);
|
|
||||||
if (NameEnd == -1 || TagEnd == -1) continue;
|
|
||||||
|
|
||||||
TString TagName = rkStr.SubString(TagIdx + 1, NameEnd - TagIdx - 1);
|
|
||||||
TString ParamString = rkStr.SubString(NameEnd + 1, TagEnd - NameEnd - 1);
|
|
||||||
if (ParamString.IsEmpty()) continue;
|
|
||||||
|
|
||||||
// Font
|
|
||||||
if (TagName == "font")
|
|
||||||
{
|
|
||||||
if (Game() >= EGame::CorruptionProto)
|
|
||||||
{
|
|
||||||
ASSERT(ParamString.StartsWith("0x"));
|
|
||||||
ParamString = ParamString.ChopFront(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(ParamString.Size() == IDLength * 2);
|
|
||||||
pTree->AddDependency( CAssetID::FromString(ParamString) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Image
|
|
||||||
else if (TagName == "image")
|
|
||||||
{
|
|
||||||
// Determine which params are textures based on image type
|
|
||||||
TStringList Params = ParamString.Split(",");
|
|
||||||
TString ImageType = Params.front();
|
|
||||||
uint32 TexturesStart = -1;
|
|
||||||
|
|
||||||
if (ImageType == "A")
|
|
||||||
TexturesStart = 2;
|
|
||||||
|
|
||||||
else if (ImageType == "SI")
|
|
||||||
TexturesStart = 3;
|
|
||||||
|
|
||||||
else if (ImageType == "SA")
|
|
||||||
TexturesStart = 4;
|
|
||||||
|
|
||||||
else if (ImageType == "B")
|
|
||||||
TexturesStart = 2;
|
|
||||||
|
|
||||||
else if (ImageType.IsHexString(false, IDLength * 2))
|
|
||||||
TexturesStart = 0;
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errorf("Unrecognized image type: %s", *ImageType);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load texture IDs
|
|
||||||
TStringList::iterator Iter = Params.begin();
|
|
||||||
|
|
||||||
for (uint32 iParam = 0; iParam < Params.size(); iParam++, Iter++)
|
|
||||||
{
|
|
||||||
if (iParam >= TexturesStart)
|
|
||||||
{
|
|
||||||
TString Param = *Iter;
|
|
||||||
|
|
||||||
if (Game() >= EGame::CorruptionProto)
|
|
||||||
{
|
|
||||||
ASSERT(Param.StartsWith("0x"));
|
|
||||||
Param = Param.ChopFront(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(Param.Size() == IDLength * 2);
|
|
||||||
pTree->AddDependency( CAssetID::FromString(Param) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pTree;
|
|
||||||
}
|
|
||||||
|
|
||||||
static TString StripFormatting(const TString& rkStr)
|
|
||||||
{
|
|
||||||
TString Out = rkStr;
|
|
||||||
int TagStart = -1;
|
|
||||||
|
|
||||||
for (uint32 iChr = 0; iChr < Out.Size(); iChr++)
|
|
||||||
{
|
|
||||||
if (Out[iChr] == '&')
|
|
||||||
{
|
|
||||||
if (TagStart == -1)
|
|
||||||
TagStart = iChr;
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Out.Remove(TagStart, 1);
|
|
||||||
TagStart = -1;
|
|
||||||
iChr--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (TagStart != -1 && Out[iChr] == ';')
|
|
||||||
{
|
|
||||||
int TagEnd = iChr + 1;
|
|
||||||
int TagLen = TagEnd - TagStart;
|
|
||||||
Out.Remove(TagStart, TagLen);
|
|
||||||
iChr = TagStart - 1;
|
|
||||||
TagStart = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Out;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CSTRINGTABLE_H
|
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
#include "CResource.h"
|
#include "CResource.h"
|
||||||
#include "CSavedStateID.h"
|
#include "CSavedStateID.h"
|
||||||
#include "CStringTable.h"
|
|
||||||
#include "Core/Resource/Area/CGameArea.h"
|
#include "Core/Resource/Area/CGameArea.h"
|
||||||
#include "Core/Resource/Model/CModel.h"
|
#include "Core/Resource/Model/CModel.h"
|
||||||
|
#include "Core/Resource/StringTable/CStringTable.h"
|
||||||
#include <Common/Math/CTransform4f.h>
|
#include <Common/Math/CTransform4f.h>
|
||||||
|
|
||||||
class CWorld : public CResource
|
class CWorld : public CResource
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
#define CSTRINGLOADER_H
|
#define CSTRINGLOADER_H
|
||||||
|
|
||||||
#include "Core/GameProject/CResourceStore.h"
|
#include "Core/GameProject/CResourceStore.h"
|
||||||
#include "Core/Resource/CStringTable.h"
|
|
||||||
#include "Core/Resource/TResPtr.h"
|
#include "Core/Resource/TResPtr.h"
|
||||||
|
#include "Core/Resource/StringTable/CStringTable.h"
|
||||||
#include <Common/EGame.h>
|
#include <Common/EGame.h>
|
||||||
|
|
||||||
class CStringLoader
|
class CStringLoader
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "CPoiToWorld.h"
|
#include "CPoiToWorld.h"
|
||||||
#include "CResource.h"
|
#include "CResource.h"
|
||||||
#include "CScan.h"
|
#include "CScan.h"
|
||||||
#include "CStringTable.h"
|
|
||||||
#include "CTexture.h"
|
#include "CTexture.h"
|
||||||
#include "CWorld.h"
|
#include "CWorld.h"
|
||||||
#include "Core/Resource/Animation/CAnimation.h"
|
#include "Core/Resource/Animation/CAnimation.h"
|
||||||
|
@ -16,6 +15,7 @@
|
||||||
#include "Core/Resource/Animation/CSkin.h"
|
#include "Core/Resource/Animation/CSkin.h"
|
||||||
#include "Core/Resource/Area/CGameArea.h"
|
#include "Core/Resource/Area/CGameArea.h"
|
||||||
#include "Core/Resource/Model/CModel.h"
|
#include "Core/Resource/Model/CModel.h"
|
||||||
|
#include "Core/Resource/StringTable/CStringTable.h"
|
||||||
|
|
||||||
#endif // RESOURCES_H
|
#endif // RESOURCES_H
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
#include "CStringTable.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listing of supported languages for different engine versions. Note we ignore the "unused" languages.
|
||||||
|
* This is also the order that languages appear in game STRG assets.
|
||||||
|
*/
|
||||||
|
// Supported languages in the original NTSC release of Metroid Prime
|
||||||
|
const ELanguage gkSupportedLanguagesMP1[] =
|
||||||
|
{
|
||||||
|
ELanguage::English
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported languages in the PAL version of Metroid Prime, and also Metroid Prime 2
|
||||||
|
const ELanguage gkSupportedLanguagesMP1PAL[] =
|
||||||
|
{
|
||||||
|
ELanguage::English, ELanguage::French, ELanguage::German,
|
||||||
|
ELanguage::Spanish, ELanguage::Italian, ELanguage::Japanese
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported languages in Metroid Prime 3
|
||||||
|
const ELanguage gkSupportedLanguagesMP3[] =
|
||||||
|
{
|
||||||
|
ELanguage::English, ELanguage::German, ELanguage::French,
|
||||||
|
ELanguage::Spanish, ELanguage::Italian, ELanguage::Japanese
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supported languages in DKCR
|
||||||
|
const ELanguage gkSupportedLanguagesDKCR[] =
|
||||||
|
{
|
||||||
|
ELanguage::English, ELanguage::Japanese, ELanguage::German,
|
||||||
|
ELanguage::French, ELanguage::Spanish, ELanguage::Italian,
|
||||||
|
ELanguage::UKEnglish, ELanguage::Korean,
|
||||||
|
ELanguage::NAFrench, ELanguage::NASpanish
|
||||||
|
};
|
||||||
|
|
||||||
|
// Utility function - retrieve the index of a given language
|
||||||
|
static int FindLanguageIndex(CStringTable* pInTable, ELanguage InLanguage)
|
||||||
|
{
|
||||||
|
for (uint LanguageIdx = 0; LanguageIdx < pInTable->NumLanguages(); LanguageIdx++)
|
||||||
|
{
|
||||||
|
if (pInTable->LanguageByIndex(LanguageIdx) == InLanguage)
|
||||||
|
{
|
||||||
|
return LanguageIdx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a string given a language/index pair */
|
||||||
|
TString CStringTable::GetString(ELanguage Language, uint StringIndex) const
|
||||||
|
{
|
||||||
|
int LanguageIdx = FindLanguageIndex(this, Language);
|
||||||
|
|
||||||
|
if (LanguageIdx >= 0 && mLanguages[LanguageIdx].Strings.size() > StringIndex)
|
||||||
|
{
|
||||||
|
return mLanguages[LanguageIdx].Strings[StringIndex];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates a string for a given language */
|
||||||
|
void CStringTable::SetString(ELanguage Language, uint StringIndex, const TString& kNewString)
|
||||||
|
{
|
||||||
|
int LanguageIdx = FindLanguageIndex(this, Language);
|
||||||
|
|
||||||
|
if (LanguageIdx >= 0 && mLanguages[LanguageIdx].Strings.size() > StringIndex)
|
||||||
|
{
|
||||||
|
mLanguages[LanguageIdx].Strings[StringIndex] = kNewString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Updates a string name */
|
||||||
|
void CStringTable::SetStringName(uint StringIndex, const TString& kNewName)
|
||||||
|
{
|
||||||
|
// Sanity check - make sure the string index is valid
|
||||||
|
ASSERT( NumStrings() > StringIndex );
|
||||||
|
|
||||||
|
// Expand the name listing if needed and assign the name
|
||||||
|
if (mStringNames.size() <= StringIndex)
|
||||||
|
{
|
||||||
|
mStringNames.resize( StringIndex + 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
mStringNames[StringIndex] = kNewName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Configures the string table with default languages for the game/region pairing of the resource */
|
||||||
|
void CStringTable::ConfigureDefaultLanguages()
|
||||||
|
{
|
||||||
|
//@todo; this should be called on all newly created string tables
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Serialize resource data */
|
||||||
|
void CStringTable::Serialize(IArchive& Arc)
|
||||||
|
{
|
||||||
|
Arc << SerialParameter("StringNames", mStringNames, SH_Optional)
|
||||||
|
<< SerialParameter("Languages", mLanguages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Build the dependency tree for this resource */
|
||||||
|
CDependencyTree* CStringTable::BuildDependencyTree() const
|
||||||
|
{
|
||||||
|
// STRGs can reference FONTs with the &font=; formatting tag and TXTRs with the &image=; tag
|
||||||
|
CDependencyTree* pTree = new CDependencyTree();
|
||||||
|
EIDLength IDLength = CAssetID::GameIDLength( Game() );
|
||||||
|
|
||||||
|
for (uint LanguageIdx = 0; LanguageIdx < mLanguages.size(); LanguageIdx++)
|
||||||
|
{
|
||||||
|
const SLanguageData& kLanguage = mLanguages[LanguageIdx];
|
||||||
|
|
||||||
|
for (uint StringIdx = 0; StringIdx < kLanguage.Strings.size(); StringIdx++)
|
||||||
|
{
|
||||||
|
const TString& kString = kLanguage.Strings[StringIdx];
|
||||||
|
|
||||||
|
for (int TagIdx = kString.IndexOf('&'); TagIdx != -1; TagIdx = kString.IndexOf('&', TagIdx + 1))
|
||||||
|
{
|
||||||
|
// Check for double ampersand (escape character in DKCR, not sure about other games)
|
||||||
|
if (kString.At(TagIdx + 1) == '&')
|
||||||
|
{
|
||||||
|
TagIdx++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tag name and parameters
|
||||||
|
int NameEnd = kString.IndexOf('=', TagIdx);
|
||||||
|
int TagEnd = kString.IndexOf(';', TagIdx);
|
||||||
|
if (NameEnd == -1 || TagEnd == -1) continue;
|
||||||
|
|
||||||
|
TString TagName = kString.SubString(TagIdx + 1, NameEnd - TagIdx - 1);
|
||||||
|
TString ParamString = kString.SubString(NameEnd + 1, TagEnd - NameEnd - 1);
|
||||||
|
if (ParamString.IsEmpty()) continue;
|
||||||
|
|
||||||
|
// Font
|
||||||
|
if (TagName == "font")
|
||||||
|
{
|
||||||
|
if (Game() >= EGame::CorruptionProto)
|
||||||
|
{
|
||||||
|
ASSERT(ParamString.StartsWith("0x"));
|
||||||
|
ParamString = ParamString.ChopFront(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(ParamString.Size() == IDLength * 2);
|
||||||
|
pTree->AddDependency( CAssetID::FromString(ParamString) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image
|
||||||
|
else if (TagName == "image")
|
||||||
|
{
|
||||||
|
// Determine which params are textures based on image type
|
||||||
|
TStringList Params = ParamString.Split(",");
|
||||||
|
TString ImageType = Params.front();
|
||||||
|
int TexturesStart = -1;
|
||||||
|
|
||||||
|
if (ImageType == "A")
|
||||||
|
TexturesStart = 2;
|
||||||
|
|
||||||
|
else if (ImageType == "SI")
|
||||||
|
TexturesStart = 3;
|
||||||
|
|
||||||
|
else if (ImageType == "SA")
|
||||||
|
TexturesStart = 4;
|
||||||
|
|
||||||
|
else if (ImageType == "B")
|
||||||
|
TexturesStart = 2;
|
||||||
|
|
||||||
|
else if (ImageType.IsHexString(false, IDLength * 2))
|
||||||
|
TexturesStart = 0;
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorf("Unrecognized image type: %s", *ImageType);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load texture IDs
|
||||||
|
TStringList::iterator Iter = Params.begin();
|
||||||
|
|
||||||
|
for (uint ParamIdx = 0; ParamIdx < Params.size(); ParamIdx++, Iter++)
|
||||||
|
{
|
||||||
|
if (ParamIdx >= TexturesStart)
|
||||||
|
{
|
||||||
|
TString Param = *Iter;
|
||||||
|
|
||||||
|
if (Game() >= EGame::CorruptionProto)
|
||||||
|
{
|
||||||
|
ASSERT(Param.StartsWith("0x"));
|
||||||
|
Param = Param.ChopFront(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(Param.Size() == IDLength * 2);
|
||||||
|
pTree->AddDependency( CAssetID::FromString(Param) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static - Strip all formatting tags for a given string */
|
||||||
|
TString CStringTable::StripFormatting(const TString& kInString)
|
||||||
|
{
|
||||||
|
TString Out = kInString;
|
||||||
|
int TagStart = -1;
|
||||||
|
|
||||||
|
for (uint CharIdx = 0; CharIdx < Out.Size(); CharIdx++)
|
||||||
|
{
|
||||||
|
if (Out[CharIdx] == '&')
|
||||||
|
{
|
||||||
|
if (TagStart == -1)
|
||||||
|
TagStart = CharIdx;
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Out.Remove(TagStart, 1);
|
||||||
|
TagStart = -1;
|
||||||
|
CharIdx--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (TagStart != -1 && Out[CharIdx] == ';')
|
||||||
|
{
|
||||||
|
int TagEnd = CharIdx + 1;
|
||||||
|
int TagLen = TagEnd - TagStart;
|
||||||
|
Out.Remove(TagStart, TagLen);
|
||||||
|
CharIdx = TagStart - 1;
|
||||||
|
TagStart = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Static - Returns whether a given language is supported by the given game/region combination */
|
||||||
|
bool CStringTable::IsLanguageSupported(ELanguage Language, EGame Game, ERegion Region)
|
||||||
|
{
|
||||||
|
// Pick the correct array to iterate based on which game/region was requested.
|
||||||
|
const ELanguage* pkSupportedLanguages = nullptr;
|
||||||
|
uint NumLanguages = 0;
|
||||||
|
|
||||||
|
if (Game <= EGame::Prime && Region == ERegion::NTSC)
|
||||||
|
{
|
||||||
|
return (Language == ELanguage::English);
|
||||||
|
}
|
||||||
|
else if (Game <= EGame::CorruptionProto)
|
||||||
|
{
|
||||||
|
pkSupportedLanguages = &gkSupportedLanguagesMP1PAL[0];
|
||||||
|
NumLanguages = ARRAY_SIZE( gkSupportedLanguagesMP1PAL );
|
||||||
|
}
|
||||||
|
else if (Game <= EGame::Corruption)
|
||||||
|
{
|
||||||
|
pkSupportedLanguages = &gkSupportedLanguagesMP3[0];
|
||||||
|
NumLanguages = ARRAY_SIZE( gkSupportedLanguagesMP3 );
|
||||||
|
}
|
||||||
|
else if (Game <= EGame::DKCReturns)
|
||||||
|
{
|
||||||
|
pkSupportedLanguages = &gkSupportedLanguagesDKCR[0];
|
||||||
|
NumLanguages = ARRAY_SIZE( gkSupportedLanguagesDKCR );
|
||||||
|
}
|
||||||
|
ASSERT(pkSupportedLangages);
|
||||||
|
ASSERT(NumLanguages > 0);
|
||||||
|
|
||||||
|
// Check if the requested language is in the array.
|
||||||
|
for (uint LanguageIdx = 0; LanguageIdx < NumLanguages; LanguageIdx++)
|
||||||
|
{
|
||||||
|
if (pkSupportedLanguages[LanguageIdx] == Language)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unsupported
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
#ifndef CSTRINGTABLE_H
|
||||||
|
#define CSTRINGTABLE_H
|
||||||
|
|
||||||
|
#include "ELanguage.h"
|
||||||
|
#include "Core/Resource/CResource.h"
|
||||||
|
#include <Common/BasicTypes.h>
|
||||||
|
#include <Common/CFourCC.h>
|
||||||
|
#include <Common/TString.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
/** A table of localized strings from STRG assets */
|
||||||
|
class CStringTable : public CResource
|
||||||
|
{
|
||||||
|
DECLARE_RESOURCE_TYPE(StringTable)
|
||||||
|
friend class CStringLoader;
|
||||||
|
|
||||||
|
/** List of string names. Optional data, can be empty. */
|
||||||
|
std::vector<TString> mStringNames;
|
||||||
|
|
||||||
|
/** String data for a language */
|
||||||
|
struct SLanguageData
|
||||||
|
{
|
||||||
|
ELanguage Language;
|
||||||
|
std::vector<TString> Strings;
|
||||||
|
|
||||||
|
void Serialize(IArchive& Arc)
|
||||||
|
{
|
||||||
|
Arc << SerialParameter("Language", Language)
|
||||||
|
<< SerialParameter("Strings", Strings);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::vector<SLanguageData> mLanguages;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Constructor */
|
||||||
|
CStringTable(CResourceEntry *pEntry = 0) : CResource(pEntry) {}
|
||||||
|
|
||||||
|
/** Returns the number of languages in the table */
|
||||||
|
inline uint NumLanguages() const { return mLanguages.size(); }
|
||||||
|
|
||||||
|
/** Returns the number of strings in the table */
|
||||||
|
inline uint NumStrings() const { return mLanguages.empty() ? 0 : mLanguages[0].Strings.size(); }
|
||||||
|
|
||||||
|
/** Returns languages used by index */
|
||||||
|
inline ELanguage LanguageByIndex(uint Index) const { return mLanguages.size() > Index ? mLanguages[Index].Language : ELanguage::Invalid; }
|
||||||
|
|
||||||
|
/** Returns the string name by string index. May be blank if the string at the requested index is unnamed */
|
||||||
|
inline TString StringNameByIndex(uint Index) const { return mStringNames.size() > Index ? mStringNames[Index] : ""; }
|
||||||
|
|
||||||
|
/** Returns a string given a language/index pair */
|
||||||
|
TString GetString(ELanguage Language, uint StringIndex) const;
|
||||||
|
|
||||||
|
/** Updates a string for a given language */
|
||||||
|
void SetString(ELanguage Language, uint StringIndex, const TString& kNewString);
|
||||||
|
|
||||||
|
/** Updates a string name */
|
||||||
|
void SetStringName(uint StringIndex, const TString& kNewName);
|
||||||
|
|
||||||
|
/** Configures the string table with default languages for the game/region pairing of the resource */
|
||||||
|
void ConfigureDefaultLanguages();
|
||||||
|
|
||||||
|
/** Serialize resource data */
|
||||||
|
virtual void Serialize(IArchive& Arc);
|
||||||
|
|
||||||
|
/** Build the dependency tree for this resource */
|
||||||
|
virtual CDependencyTree* BuildDependencyTree() const;
|
||||||
|
|
||||||
|
/** Static - Strip all formatting tags for a given string */
|
||||||
|
static TString StripFormatting(const TString& kInString);
|
||||||
|
|
||||||
|
/** Static - Returns whether a given language is supported by the given game/region combination */
|
||||||
|
static bool IsLanguageSupported(ELanguage Language, EGame Game, ERegion Region);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSTRINGTABLE_H
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef ELANGUAGE_H
|
||||||
|
#define ELANGUAGE_H
|
||||||
|
|
||||||
|
#include <Common/CFourCC.h>
|
||||||
|
|
||||||
|
/** A language in the game's localization system */
|
||||||
|
enum class ELanguage
|
||||||
|
{
|
||||||
|
// The original release of Metroid Prime only supported English
|
||||||
|
English = FOURCC('ENGL'),
|
||||||
|
// Support for these languages was added in the PAL version of Metroid Prime
|
||||||
|
German = FOURCC('GERM'),
|
||||||
|
French = FOURCC('FREN'),
|
||||||
|
Spanish = FOURCC('SPAN'),
|
||||||
|
Italian = FOURCC('ITAL'),
|
||||||
|
Dutch = FOURCC('DUTC'), // Unused
|
||||||
|
Japanese = FOURCC('JAPN'),
|
||||||
|
// The rest of these languages were added in Metroid Prime 3
|
||||||
|
SimplifiedChinese = FOURCC('SCHN'), // Unused
|
||||||
|
TraditionalChinese = FOURCC('TCHN'), // Unused
|
||||||
|
UKEnglish = FOURCC('UKEN'),
|
||||||
|
Korean = FOURCC('KORE'),
|
||||||
|
NAFrench = FOURCC('NAFR'),
|
||||||
|
NASpanish = FOURCC('NASP'),
|
||||||
|
// Invalid
|
||||||
|
Invalid = FOURCC('INVD')
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ELANGUAGE_H
|
Loading…
Reference in New Issue