mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
ces: implement CP932 string conversion
This commit is contained in:
@@ -3003,186 +3003,6 @@ LIB_DEFINE(InitNet_1_NpUniversalDataSystem) {
|
||||
|
||||
} // namespace LibNpUniversalDataSystem
|
||||
|
||||
namespace LibCes {
|
||||
|
||||
LIB_VERSION("Ces", 1, "Ces", 1, 1);
|
||||
|
||||
static const uint8_t* KYTY_SYSV_ABI CesRefersUcsProfileCp1252() {
|
||||
PRINT_NAME();
|
||||
|
||||
static const uint8_t profile = 0;
|
||||
return &profile;
|
||||
}
|
||||
|
||||
static uint32_t CesDecodeUtf8(const uint8_t* utf8, uint32_t utf8max, uint32_t* utf8_len) {
|
||||
if (utf8 == nullptr || utf8max == 0) {
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = 0;
|
||||
}
|
||||
return 0xfffd;
|
||||
}
|
||||
|
||||
const uint8_t c0 = utf8[0];
|
||||
if (c0 < 0x80) {
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = 1;
|
||||
}
|
||||
return c0;
|
||||
}
|
||||
if ((c0 & 0xe0) == 0xc0 && utf8max >= 2 && (utf8[1] & 0xc0) == 0x80) {
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = 2;
|
||||
}
|
||||
return ((c0 & 0x1f) << 6u) | (utf8[1] & 0x3fu);
|
||||
}
|
||||
if ((c0 & 0xf0) == 0xe0 && utf8max >= 3 && (utf8[1] & 0xc0) == 0x80 &&
|
||||
(utf8[2] & 0xc0) == 0x80) {
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = 3;
|
||||
}
|
||||
return ((c0 & 0x0f) << 12u) | ((utf8[1] & 0x3fu) << 6u) | (utf8[2] & 0x3fu);
|
||||
}
|
||||
if ((c0 & 0xf8) == 0xf0 && utf8max >= 4 && (utf8[1] & 0xc0) == 0x80 &&
|
||||
(utf8[2] & 0xc0) == 0x80 && (utf8[3] & 0xc0) == 0x80) {
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = 4;
|
||||
}
|
||||
return ((c0 & 0x07) << 18u) | ((utf8[1] & 0x3fu) << 12u) | ((utf8[2] & 0x3fu) << 6u) |
|
||||
(utf8[3] & 0x3fu);
|
||||
}
|
||||
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = 1;
|
||||
}
|
||||
return 0xfffd;
|
||||
}
|
||||
|
||||
struct Cp1252Mapping {
|
||||
uint8_t cp1252;
|
||||
uint32_t unicode;
|
||||
};
|
||||
|
||||
static constexpr Cp1252Mapping CP1252_EXTENDED_MAP[] = {
|
||||
{0x80, 0x20ac}, {0x82, 0x201a}, {0x83, 0x0192}, {0x84, 0x201e}, {0x85, 0x2026}, {0x86, 0x2020},
|
||||
{0x87, 0x2021}, {0x88, 0x02c6}, {0x89, 0x2030}, {0x8a, 0x0160}, {0x8b, 0x2039}, {0x8c, 0x0152},
|
||||
{0x8e, 0x017d}, {0x91, 0x2018}, {0x92, 0x2019}, {0x93, 0x201c}, {0x94, 0x201d}, {0x95, 0x2022},
|
||||
{0x96, 0x2013}, {0x97, 0x2014}, {0x98, 0x02dc}, {0x99, 0x2122}, {0x9a, 0x0161}, {0x9b, 0x203a},
|
||||
{0x9c, 0x0153}, {0x9e, 0x017e}, {0x9f, 0x0178},
|
||||
};
|
||||
|
||||
static uint8_t CesUnicodeToCp1252(uint32_t code) {
|
||||
if (code <= 0x7f || (code >= 0xa0 && code <= 0xff)) {
|
||||
return static_cast<uint8_t>(code);
|
||||
}
|
||||
|
||||
for (const auto& map: CP1252_EXTENDED_MAP) {
|
||||
if (map.unicode == code) {
|
||||
return map.cp1252;
|
||||
}
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
|
||||
static uint32_t CesCp1252ToUnicode(uint8_t sbc) {
|
||||
if (sbc <= 0x7f || sbc >= 0xa0) {
|
||||
return sbc;
|
||||
}
|
||||
|
||||
for (const auto& map: CP1252_EXTENDED_MAP) {
|
||||
if (map.cp1252 == sbc) {
|
||||
return map.unicode;
|
||||
}
|
||||
}
|
||||
return sbc;
|
||||
}
|
||||
|
||||
static uint32_t CesEncodeUtf8(uint32_t code, uint8_t* utf8, uint32_t utf8max) {
|
||||
uint8_t tmp[4] {};
|
||||
uint32_t len = 0;
|
||||
|
||||
if (code <= 0x7f) {
|
||||
tmp[0] = static_cast<uint8_t>(code);
|
||||
len = 1;
|
||||
} else if (code <= 0x7ff) {
|
||||
tmp[0] = static_cast<uint8_t>(0xc0u | ((code >> 6u) & 0x1fu));
|
||||
tmp[1] = static_cast<uint8_t>(0x80u | (code & 0x3fu));
|
||||
len = 2;
|
||||
} else if (code <= 0xffff) {
|
||||
tmp[0] = static_cast<uint8_t>(0xe0u | ((code >> 12u) & 0x0fu));
|
||||
tmp[1] = static_cast<uint8_t>(0x80u | ((code >> 6u) & 0x3fu));
|
||||
tmp[2] = static_cast<uint8_t>(0x80u | (code & 0x3fu));
|
||||
len = 3;
|
||||
} else {
|
||||
tmp[0] = static_cast<uint8_t>(0xf0u | ((code >> 18u) & 0x07u));
|
||||
tmp[1] = static_cast<uint8_t>(0x80u | ((code >> 12u) & 0x3fu));
|
||||
tmp[2] = static_cast<uint8_t>(0x80u | ((code >> 6u) & 0x3fu));
|
||||
tmp[3] = static_cast<uint8_t>(0x80u | (code & 0x3fu));
|
||||
len = 4;
|
||||
}
|
||||
|
||||
if (utf8 != nullptr && utf8max >= len) {
|
||||
std::memcpy(utf8, tmp, len);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI CesUtf8ToSbc(const uint8_t* utf8, uint32_t utf8max, uint32_t* utf8_len,
|
||||
const uint8_t* profile, uint8_t* sbc) {
|
||||
PRINT_NAME();
|
||||
|
||||
if (sbc == nullptr || profile == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t local_len = 0;
|
||||
const auto code = CesDecodeUtf8(utf8, utf8max, &local_len);
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = local_len;
|
||||
}
|
||||
*sbc = CesUnicodeToCp1252(code);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI CesSbcToUtf8(const uint8_t* profile, uint8_t sbc, uint8_t* utf8,
|
||||
uint32_t utf8max, uint32_t* utf8_len) {
|
||||
PRINT_NAME();
|
||||
|
||||
if (profile == nullptr || utf8 == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const auto code = CesCp1252ToUnicode(sbc);
|
||||
const auto len = CesEncodeUtf8(code, utf8, utf8max);
|
||||
if (utf8_len != nullptr) {
|
||||
*utf8_len = len;
|
||||
}
|
||||
|
||||
return utf8max >= len ? 0 : -1;
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI CesStub(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3) {
|
||||
PRINT_NAME();
|
||||
|
||||
(void)arg0;
|
||||
(void)arg1;
|
||||
(void)arg2;
|
||||
(void)arg3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitNet_1_Ces) {
|
||||
LIB_FUNC("ZiDCxUUGbec", LibCes::CesStub);
|
||||
LIB_FUNC("538bRGc6Zo8", LibCes::CesStub);
|
||||
LIB_FUNC("LPzYZ+FR0BI", LibCes::CesRefersUcsProfileCp1252);
|
||||
LIB_FUNC("3Q1gOWWarcw", LibCes::CesUtf8ToSbc);
|
||||
LIB_FUNC("xTd54EEL1Ao", LibCes::CesSbcToUtf8);
|
||||
}
|
||||
|
||||
} // namespace LibCes
|
||||
|
||||
namespace LibNpGameIntent {
|
||||
|
||||
LIB_VERSION("NpGameIntent", 1, "NpGameIntent", 1, 1);
|
||||
@@ -3992,7 +3812,6 @@ LIB_DEFINE(InitNet_1) {
|
||||
LibNpAuth::InitNet_1_NpAuth(s);
|
||||
LibNpTrophy2::InitNet_1_NpTrophy2(s);
|
||||
LibNpUniversalDataSystem::InitNet_1_NpUniversalDataSystem(s);
|
||||
LibCes::InitNet_1_Ces(s);
|
||||
LibNpGameIntent::InitNet_1_NpGameIntent(s);
|
||||
LibNpWebApi2::InitNet_1_NpWebApi2(s);
|
||||
LibGameUpdate::InitNet_1_GameUpdate(s);
|
||||
|
||||
Reference in New Issue
Block a user