From d6482874d622ee666cd840269a49704e337c001e Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Wed, 25 Jan 2017 22:09:22 -1000 Subject: [PATCH] Path-substitution integrated into MP1 STRG cook/uncook --- DataSpec/DNACommon/STRG.cpp | 1 + DataSpec/DNAMP1/STRG.cpp | 260 ++++++++++++++++++++++++++++++++- DataSpec/DNAMP1/STRG.hpp | 10 +- DataSpec/DNAMP2/STRG.hpp | 10 +- DataSpec/DNAMP3/STRG.hpp | 10 +- Runtime/GuiSys/CTextParser.cpp | 10 +- hecl | 2 +- 7 files changed, 280 insertions(+), 23 deletions(-) diff --git a/DataSpec/DNACommon/STRG.cpp b/DataSpec/DNACommon/STRG.cpp index ae8fb5353..9ab09973d 100644 --- a/DataSpec/DNACommon/STRG.cpp +++ b/DataSpec/DNACommon/STRG.cpp @@ -41,6 +41,7 @@ std::unique_ptr LoadSTRG(athena::io::IStreamReader& reader) newStrg->_read(reader); return std::unique_ptr(newStrg); } + default: break; } return std::unique_ptr(); } diff --git a/DataSpec/DNAMP1/STRG.cpp b/DataSpec/DNAMP1/STRG.cpp index 0d6e3d010..aea94a8f7 100644 --- a/DataSpec/DNAMP1/STRG.cpp +++ b/DataSpec/DNAMP1/STRG.cpp @@ -17,6 +17,262 @@ const std::vector skLanguages = FOURCC('JAPN') }; +static float u16stof(char16_t* str) +{ + char cstr[16]; + int i; + for (i=0 ; i<15 && str[i] != u'\0' ; ++i) + cstr[i] = str[i]; + cstr[i] = '\0'; + return strtof(cstr, nullptr); +} + +static uint32_t ParseTag(const char16_t* str) +{ + char parseStr[9]; + int i; + for (i=0 ; i<8 && str[i] ; ++i) + parseStr[i] = str[i]; + parseStr[i] = '\0'; + return strtol(parseStr, nullptr, 16); +} + +static std::u16string::const_iterator SkipCommas(std::u16string& ret, + const std::u16string& str, + std::u16string::const_iterator it, + size_t count) +{ + for (size_t i=0 ; i( + hecl::Char16ToUTF8(std::u16string(it, endIt))); + ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); + it = endIt; + if (*it == u';') + { + ret.push_back(u';'); + return it + 1; + } + else if (*it == u',') + { + ret.push_back(u','); + ++it; + } + else + { + break; + } + } + + /* Failsafe */ + auto scpos = str.find(u';', it - str.begin()); + if (scpos == std::u16string::npos) + return str.end(); + return str.begin() + scpos + 1; +} + +static std::u16string UncookString(const std::u16string& str) +{ + std::u16string ret; + ret.reserve(str.size()); + for (auto it = str.begin() ; it != str.end() ;) + { + if (*it == u'&') + { + ret.push_back(u'&'); + ++it; + if (!str.compare(it - str.begin(), 5, u"image")) + { + ret.append(u"image="); + it += 6; + if (!str.compare(it - str.begin(), 1, u"A")) + { + it = SkipCommas(ret, str, it, 2); + it = UncookTextureList(ret, str, it); + continue; + } + else if (!str.compare(it - str.begin(), 2, u"SA")) + { + it = SkipCommas(ret, str, it, 4); + it = UncookTextureList(ret, str, it); + continue; + } + else if (!str.compare(it - str.begin(), 2, u"SI")) + { + it = SkipCommas(ret, str, it, 3); + it = UncookTextureList(ret, str, it); + continue; + } + } + else if (!str.compare(it - str.begin(), 4, u"font")) + { + ret.append(u"font="); + it += 5; + UniqueID32 id = ParseTag(&*it); + hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id, true); + ret.append(hecl::UTF8ToChar16(path ? path.getRelativePathUTF8() : id.toString())); + + ret.push_back(u';'); + auto scpos = str.find(u';', it - str.begin()); + if (scpos == std::u16string::npos) + it = str.end(); + else + it = str.begin() + scpos + 1; + } + else + { + auto scpos = str.find(u';', it - str.begin()); + if (scpos == std::u16string::npos) + { + it = str.end(); + } + else + { + auto end = str.begin() + scpos + 1; + ret.insert(ret.end(), it, end); + it = end; + } + } + } + else + { + ret.push_back(*it); + ++it; + } + } + return ret; +} + +static std::u16string CookString(const std::u16string& str) +{ + std::u16string ret; + ret.reserve(str.size()); + for (auto it = str.begin() ; it != str.end() ;) + { + if (*it == u'&') + { + ret.push_back(u'&'); + ++it; + if (!str.compare(it - str.begin(), 5, u"image")) + { + ret.append(u"image="); + it += 6; + if (!str.compare(it - str.begin(), 1, u"A")) + { + it = SkipCommas(ret, str, it, 2); + it = CookTextureList(ret, str, it); + continue; + } + else if (!str.compare(it - str.begin(), 2, u"SA")) + { + it = SkipCommas(ret, str, it, 4); + it = CookTextureList(ret, str, it); + continue; + } + else if (!str.compare(it - str.begin(), 2, u"SI")) + { + it = SkipCommas(ret, str, it, 3); + it = CookTextureList(ret, str, it); + continue; + } + } + else if (!str.compare(it - str.begin(), 4, u"font")) + { + ret.append(u"font="); + it += 5; + auto end = str.find(u',', it - str.begin()); + if (end == std::u16string::npos) + Log.report(logvisor::Fatal, "Missing comma token while pasing font tag"); + hecl::ProjectPath path = + UniqueIDBridge::MakePathFromString( + hecl::Char16ToUTF8(std::u16string(it, str.begin() + end + 1))); + ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); + + ret.push_back(u';'); + auto scpos = str.find(u';', it - str.begin()); + if (scpos == std::u16string::npos) + it = str.end(); + else + it = str.begin() + scpos + 1; + } + else + { + auto scpos = str.find(u';', it - str.begin()); + if (scpos == std::u16string::npos) + { + it = str.end(); + } + else + { + auto end = str.begin() + scpos + 1; + ret.insert(ret.end(), it, end); + it = end; + } + } + } + else + { + ret.push_back(*it); + ++it; + } + } + return ret; +} + void STRG::_read(athena::io::IStreamReader& reader) { atUint32 langCount = reader.readUint32Big(); @@ -47,7 +303,7 @@ void STRG::_read(athena::io::IStreamReader& reader) atUint32 strOffset = reader.readUint32Big(); atUint32 tmpOffset = reader.position(); reader.seek(langStart + strOffset, athena::SeekOrigin::Begin); - strs.emplace_back(reader.readU16StringBig()); + strs.emplace_back(UncookString(reader.readU16StringBig())); reader.seek(tmpOffset, athena::SeekOrigin::Begin); } langs.emplace_back(lang.first, strs); @@ -123,7 +379,7 @@ void STRG::write(athena::io::IStreamWriter& writer) const for (atUint32 s=0 ; s>> langs; std::unordered_map*> langMap; - inline int32_t lookupIdx(const std::string& name) const {return -1;} + int32_t lookupIdx(const std::string& name) const {return -1;} - inline size_t count() const + size_t count() const { size_t retval = 0; for (const auto& item : langs) @@ -32,21 +32,21 @@ struct STRG : ISTRG } return retval; } - inline std::string getUTF8(const FourCC& lang, size_t idx) const + std::string getUTF8(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) return hecl::Char16ToUTF8(search->second->at(idx)); return std::string(); } - inline std::u16string getUTF16(const FourCC& lang, size_t idx) const + std::u16string getUTF16(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) return search->second->at(idx); return std::u16string(); } - inline hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const + hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) diff --git a/DataSpec/DNAMP2/STRG.hpp b/DataSpec/DNAMP2/STRG.hpp index 88348ea6c..840a12165 100644 --- a/DataSpec/DNAMP2/STRG.hpp +++ b/DataSpec/DNAMP2/STRG.hpp @@ -19,7 +19,7 @@ struct STRG : ISTRG std::unordered_map*> langMap; std::map names; - inline int32_t lookupIdx(const std::string& name) const + int32_t lookupIdx(const std::string& name) const { auto search = names.find(name); if (search == names.end()) @@ -27,7 +27,7 @@ struct STRG : ISTRG return search->second; } - inline size_t count() const + size_t count() const { size_t retval = 0; for (const auto& item : langs) @@ -38,21 +38,21 @@ struct STRG : ISTRG } return retval; } - inline std::string getUTF8(const FourCC& lang, size_t idx) const + std::string getUTF8(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) return hecl::Char16ToUTF8(search->second->at(idx)); return std::string(); } - inline std::u16string getUTF16(const FourCC& lang, size_t idx) const + std::u16string getUTF16(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) return search->second->at(idx); return std::u16string(); } - inline hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const + hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) diff --git a/DataSpec/DNAMP3/STRG.hpp b/DataSpec/DNAMP3/STRG.hpp index 3bd4e1795..c3fb57f70 100644 --- a/DataSpec/DNAMP3/STRG.hpp +++ b/DataSpec/DNAMP3/STRG.hpp @@ -19,7 +19,7 @@ struct STRG : ISTRG std::unordered_map*> langMap; std::map names; - inline int32_t lookupIdx(const std::string& name) const + int32_t lookupIdx(const std::string& name) const { auto search = names.find(name); if (search == names.end()) @@ -27,7 +27,7 @@ struct STRG : ISTRG return search->second; } - inline size_t count() const + size_t count() const { size_t retval = 0; for (const auto& item : langs) @@ -38,21 +38,21 @@ struct STRG : ISTRG } return retval; } - inline std::string getUTF8(const FourCC& lang, size_t idx) const + std::string getUTF8(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) return search->second->at(idx); return std::string(); } - inline std::u16string getUTF16(const FourCC& lang, size_t idx) const + std::u16string getUTF16(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) return hecl::UTF8ToChar16(search->second->at(idx)); return std::u16string(); } - inline hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const + hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const { auto search = langMap.find(lang); if (search != langMap.end()) diff --git a/Runtime/GuiSys/CTextParser.cpp b/Runtime/GuiSys/CTextParser.cpp index 309afd61d..dd4ee7b7c 100644 --- a/Runtime/GuiSys/CTextParser.cpp +++ b/Runtime/GuiSys/CTextParser.cpp @@ -7,12 +7,12 @@ namespace urde static float u16stof(char16_t* str) { - wchar_t wstr[16]; + char cstr[16]; int i; for (i=0 ; i<15 && str[i] != u'\0' ; ++i) - wstr[i] = str[i]; - wstr[i+1] = L'\0'; - return std::wcstof(wstr, nullptr); + cstr[i] = str[i]; + cstr[i] = '\0'; + return strtof(cstr, nullptr); } CTextColor CTextParser::ParseColor(const char16_t* str, int len) @@ -325,7 +325,7 @@ void CTextParser::ParseText(CTextExecuteBuffer& out, const char16_t* str, int le while (str[e] && (len == -1 || e < len) && str[e] != u';') ++e; - ParseTag(out, str + e, e - b); + ParseTag(out, str + b, e - b); b = e + 1; } else diff --git a/hecl b/hecl index 5d797e53e..1a079c247 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 5d797e53ecffbbf2e612bc0e21eed2c495985ca0 +Subproject commit 1a079c247e07d1b3c4ebc384db27274f56a5e1a2