2019-09-01 07:10:24 +00:00
|
|
|
#include "Runtime/GuiSys/CStringTable.hpp"
|
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
#include "Runtime/CBasics.hpp"
|
|
|
|
#include "Runtime/CInputStream.hpp"
|
2019-09-01 07:10:24 +00:00
|
|
|
#include "Runtime/CToken.hpp"
|
2016-08-16 21:05:33 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
#include <array>
|
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce {
|
2019-09-01 07:10:24 +00:00
|
|
|
namespace {
|
|
|
|
constexpr std::array languages{
|
|
|
|
FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'), FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN'),
|
|
|
|
};
|
|
|
|
} // Anonymous namespace
|
2016-08-16 21:05:33 +00:00
|
|
|
|
2019-09-01 07:10:24 +00:00
|
|
|
FourCC CStringTable::mCurrentLanguage = languages[0];
|
2016-08-16 21:05:33 +00:00
|
|
|
|
|
|
|
CStringTable::CStringTable(CInputStream& in) { LoadStringTable(in); }
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CStringTable::LoadStringTable(CInputStream& in) {
|
2022-02-18 07:37:54 +00:00
|
|
|
in.ReadLong();
|
|
|
|
in.ReadLong();
|
|
|
|
u32 langCount = in.ReadLong();
|
|
|
|
x0_stringCount = in.ReadLong();
|
2018-12-08 05:30:43 +00:00
|
|
|
std::vector<std::pair<FourCC, u32>> langOffsets;
|
|
|
|
for (u32 i = 0; i < langCount; ++i) {
|
2022-02-18 07:37:54 +00:00
|
|
|
FourCC fcc;
|
|
|
|
in.Get(reinterpret_cast<u8*>(&fcc), 4);
|
|
|
|
u32 off = in.ReadLong();
|
2018-12-08 05:30:43 +00:00
|
|
|
langOffsets.emplace_back(fcc, off);
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 lang = 0;
|
|
|
|
u32 offset = 0;
|
|
|
|
while ((langCount--) > 0) {
|
|
|
|
if (langOffsets[lang].first == mCurrentLanguage) {
|
|
|
|
offset = langOffsets[lang].second;
|
|
|
|
break;
|
2016-08-16 21:05:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
lang++;
|
|
|
|
}
|
2016-08-16 21:05:33 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
/*
|
|
|
|
* If we fail to get a language, default to the first in the list
|
|
|
|
* This way we always display _something_
|
|
|
|
*/
|
2019-06-12 02:05:17 +00:00
|
|
|
if (offset == UINT32_MAX)
|
2018-12-08 05:30:43 +00:00
|
|
|
offset = langOffsets[0].second;
|
2016-08-17 05:40:25 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
for (u32 i = 0; i < offset; ++i) {
|
|
|
|
in.ReadChar();
|
|
|
|
}
|
2016-08-16 21:05:33 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
u32 dataLen = in.ReadLong();
|
2018-12-08 05:30:43 +00:00
|
|
|
m_bufLen = dataLen;
|
|
|
|
x4_data.reset(new u8[dataLen]);
|
2022-02-18 07:37:54 +00:00
|
|
|
in.Get(x4_data.get(), dataLen);
|
2017-01-22 01:40:12 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
#if METAFORCE_TARGET_BYTE_ORDER == __ORDER_LITTLE_ENDIAN__
|
2018-12-08 05:30:43 +00:00
|
|
|
u32* off = reinterpret_cast<u32*>(x4_data.get());
|
2022-02-18 07:37:54 +00:00
|
|
|
for (u32 i = 0; i < x0_stringCount; ++i, ++off) {
|
|
|
|
*off = CBasics::SwapBytes(*off);
|
|
|
|
}
|
2017-01-22 01:40:12 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
for (u32 i = x0_stringCount * 4; i < dataLen; i += 2) {
|
|
|
|
u16* chr = reinterpret_cast<u16*>(x4_data.get() + i);
|
2022-02-18 07:37:54 +00:00
|
|
|
*chr = CBasics::SwapBytes(*chr);
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2022-02-18 07:37:54 +00:00
|
|
|
#endif
|
2016-08-16 21:05:33 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
const char16_t* CStringTable::GetString(s32 str) const {
|
|
|
|
if (str < 0 || u32(str) >= x0_stringCount)
|
|
|
|
return u"Invalid";
|
2016-08-16 21:05:33 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
u32 off = *reinterpret_cast<u32*>(x4_data.get() + str * 4);
|
|
|
|
return reinterpret_cast<char16_t*>(x4_data.get() + off);
|
2016-08-16 21:05:33 +00:00
|
|
|
}
|
|
|
|
|
2019-09-01 07:10:24 +00:00
|
|
|
void CStringTable::SetLanguage(s32 lang) { mCurrentLanguage = languages[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&,
|
2020-04-24 01:24:39 +00:00
|
|
|
[[maybe_unused]] CObjectReference* selfRef) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return TToken<CStringTable>::GetIObjObjectFor(std::make_unique<CStringTable>(in));
|
2016-08-16 21:12:27 +00:00
|
|
|
}
|
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce
|