2016-08-16 21:05:33 +00:00
|
|
|
#include "CStringTable.hpp"
|
2016-08-16 21:12:27 +00:00
|
|
|
#include "CToken.hpp"
|
2016-08-16 21:05:33 +00:00
|
|
|
|
|
|
|
namespace urde
|
|
|
|
{
|
|
|
|
const std::vector<FourCC> CStringTable::skLanguages =
|
|
|
|
{
|
2017-01-21 16:58:43 +00:00
|
|
|
FOURCC('ENGL'),
|
|
|
|
FOURCC('FREN'),
|
|
|
|
FOURCC('GERM'),
|
|
|
|
FOURCC('SPAN'),
|
|
|
|
FOURCC('ITAL'),
|
|
|
|
FOURCC('DUTC'),
|
|
|
|
FOURCC('JAPN')
|
2016-08-16 21:05:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
FourCC CStringTable::mCurrentLanguage = CStringTable::skLanguages[0];
|
|
|
|
|
|
|
|
CStringTable::CStringTable(CInputStream& in) { LoadStringTable(in); }
|
|
|
|
|
|
|
|
void CStringTable::LoadStringTable(CInputStream &in)
|
|
|
|
{
|
|
|
|
in.readUint32Big();
|
|
|
|
in.readUint32Big();
|
|
|
|
u32 langCount = in.readUint32Big();
|
|
|
|
x0_stringCount = in.readUint32Big();
|
|
|
|
std::vector<std::pair<FourCC, u32>> langOffsets;
|
|
|
|
for (u32 i = 0 ; i<langCount ; ++i)
|
|
|
|
{
|
2016-08-17 05:40:25 +00:00
|
|
|
FourCC fcc(in.readUint32());
|
2016-08-16 21:05:33 +00:00
|
|
|
u32 off = in.readUint32Big();
|
|
|
|
langOffsets.emplace_back(fcc,off);
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 lang = 0;
|
|
|
|
u32 offset = 0;
|
|
|
|
while((langCount--) > 0)
|
|
|
|
{
|
|
|
|
if (langOffsets[lang].first == mCurrentLanguage)
|
|
|
|
{
|
|
|
|
offset = langOffsets[lang].second;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
lang++;
|
|
|
|
}
|
|
|
|
|
2016-08-17 05:40:25 +00:00
|
|
|
/*
|
|
|
|
* If we fail to get a language, default to the first in the list
|
|
|
|
* This way we always display _something_
|
|
|
|
*/
|
|
|
|
if (offset == -1)
|
|
|
|
offset = langOffsets[0].second;
|
|
|
|
|
2016-08-16 21:05:33 +00:00
|
|
|
in.seek(offset);
|
|
|
|
|
|
|
|
u32 dataLen = in.readUint32Big();
|
|
|
|
m_bufLen = dataLen;
|
|
|
|
x4_data.reset(new u8[dataLen]);
|
|
|
|
in.readUBytesToBuf(x4_data.get(), dataLen);
|
2017-01-21 16:58:43 +00:00
|
|
|
for (u32 i = 0 ; i < (x0_stringCount * 4) ; i += 4)
|
2016-08-16 21:05:33 +00:00
|
|
|
{
|
|
|
|
u32* off = reinterpret_cast<u32*>(x4_data.get() + i);
|
|
|
|
*off = hecl::SBig(*off);
|
|
|
|
}
|
|
|
|
for (u32 i = x0_stringCount * 4 ; i<dataLen ; i += 2)
|
|
|
|
{
|
2016-08-17 05:40:25 +00:00
|
|
|
u16* chr = reinterpret_cast<u16*>(x4_data.get() + i);
|
2016-08-16 21:05:33 +00:00
|
|
|
*chr = hecl::SBig(*chr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::wstring CStringTable::GetString(s32 str) const
|
|
|
|
{
|
2016-12-21 19:27:15 +00:00
|
|
|
if (str < 0 || u32(str) >= x0_stringCount)
|
2016-08-16 21:05:33 +00:00
|
|
|
return L"Invalid";
|
|
|
|
|
2017-01-21 16:58:43 +00:00
|
|
|
u32 off = *(reinterpret_cast<u32*>(x4_data.get() + (str * 4)));
|
2016-08-16 21:05:33 +00:00
|
|
|
CMemoryInStream tmp(x4_data.get() + off, m_bufLen - off);
|
|
|
|
return tmp.readWString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CStringTable::SetLanguage(s32 lang)
|
|
|
|
{
|
|
|
|
mCurrentLanguage = skLanguages[lang];
|
|
|
|
}
|
2016-08-16 21:12:27 +00:00
|
|
|
|
2016-09-02 19:32:57 +00:00
|
|
|
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
|
|
|
|
CObjectReference* selfRef)
|
2016-08-16 21:12:27 +00:00
|
|
|
{
|
|
|
|
return TToken<CStringTable>::GetIObjObjectFor(std::make_unique<CStringTable>(in));
|
|
|
|
}
|
|
|
|
|
2016-08-16 21:05:33 +00:00
|
|
|
}
|