[C++] Uplift version to C++20

This commit is contained in:
Gliniak 2024-12-25 12:05:27 +01:00 committed by Radosław Gliński
parent a6e3d77504
commit c3586bc165
24 changed files with 175 additions and 162 deletions

View File

@ -26,7 +26,7 @@ defines({
"UNICODE", "UNICODE",
}) })
cppdialect("C++17") cppdialect("C++20")
exceptionhandling("On") exceptionhandling("On")
rtti("On") rtti("On")
symbols("On") symbols("On")

View File

@ -1462,17 +1462,17 @@ void EmulatorWindow::UpdateTitle() {
// Title information, if available // Title information, if available
if (emulator()->is_title_open()) { if (emulator()->is_title_open()) {
sb.AppendFormat(u8" | [{:08X}", emulator()->title_id()); sb.AppendFormat(" | [{:08X}", emulator()->title_id());
auto title_version = emulator()->title_version(); auto title_version = emulator()->title_version();
if (!title_version.empty()) { if (!title_version.empty()) {
sb.Append(u8" v"); sb.Append(" v");
sb.Append(title_version); sb.Append(title_version);
} }
sb.Append(u8"]"); sb.Append("]");
auto title_name = emulator()->title_name(); auto title_name = emulator()->title_name();
if (!title_name.empty()) { if (!title_name.empty()) {
sb.Append(u8" "); sb.Append(" ");
sb.Append(title_name); sb.Append(title_name);
} }
} }
@ -1482,28 +1482,28 @@ void EmulatorWindow::UpdateTitle() {
if (graphics_system) { if (graphics_system) {
auto graphics_name = graphics_system->name(); auto graphics_name = graphics_system->name();
if (!graphics_name.empty()) { if (!graphics_name.empty()) {
sb.Append(u8" <"); sb.Append(" <");
sb.Append(graphics_name); sb.Append(graphics_name);
sb.Append(u8">"); sb.Append(">");
} }
} }
if (Clock::guest_time_scalar() != 1.0) { if (Clock::guest_time_scalar() != 1.0) {
sb.AppendFormat(u8" (@{:.2f}x)", Clock::guest_time_scalar()); sb.AppendFormat(" (@{:.2f}x)", Clock::guest_time_scalar());
} }
if (initializing_shader_storage_) { if (initializing_shader_storage_) {
sb.Append(u8" (Preloading shaders\u2026)"); sb.Append(" (Preloading shaders\u2026)");
} }
patcher::Patcher* patcher = emulator()->patcher(); patcher::Patcher* patcher = emulator()->patcher();
if (patcher && patcher->IsAnyPatchApplied()) { if (patcher && patcher->IsAnyPatchApplied()) {
sb.Append(u8" [Patches Applied]"); sb.Append(" [Patches Applied]");
} }
patcher::PluginLoader* pluginloader = emulator()->plugin_loader(); patcher::PluginLoader* pluginloader = emulator()->plugin_loader();
if (pluginloader && pluginloader->IsAnyPluginLoaded()) { if (pluginloader && pluginloader->IsAnyPluginLoaded()) {
sb.Append(u8" [Plugins Loaded]"); sb.Append(" [Plugins Loaded]");
} }
window_->SetTitle(sb.to_string_view()); window_->SetTitle(sb.to_string_view());
@ -1873,8 +1873,8 @@ void EmulatorWindow::ToggleGPUSetting(gpu_cvar value) {
// Determine if the Xbox Gamebar is enabled via the Windows registry // Determine if the Xbox Gamebar is enabled via the Windows registry
bool EmulatorWindow::IsUseNexusForGameBarEnabled() { bool EmulatorWindow::IsUseNexusForGameBarEnabled() {
#ifdef _WIN32 #ifdef _WIN32
const LPWSTR reg_path = L"SOFTWARE\\Microsoft\\GameBar"; const LPCWSTR reg_path = L"SOFTWARE\\Microsoft\\GameBar";
const LPWSTR key = L"UseNexusForGameBarEnabled"; const LPCWSTR key = L"UseNexusForGameBarEnabled";
DWORD value = 0; DWORD value = 0;
DWORD dataSize = sizeof(value); DWORD dataSize = sizeof(value);

View File

@ -110,24 +110,24 @@ std::string EscapeBasicString(const std::string_view view) {
for (auto it = begin; it != end; ++it) { for (auto it = begin; it != end; ++it) {
auto c = *it; auto c = *it;
if (c == '\b') { if (c == '\b') {
result += u8"\\b"; result += "\\b";
} else if (c == '\t') { } else if (c == '\t') {
result += u8"\\t"; result += "\\t";
} else if (c == '\n') { } else if (c == '\n') {
result += u8"\\n"; result += "\\n";
} else if (c == '\f') { } else if (c == '\f') {
result += u8"\\f"; result += "\\f";
} else if (c == '\r') { } else if (c == '\r') {
result += u8"\\r"; result += "\\r";
} else if (c == '"') { } else if (c == '"') {
result += u8"\\\""; result += "\\\"";
} else if (c == '\\') { } else if (c == '\\') {
result += u8"\\\\"; result += "\\\\";
} else if (c < 0x20 || c == 0x7F) { } else if (c < 0x20 || c == 0x7F) {
if (c <= 0xFFFF) { if (c <= 0xFFFF) {
result += fmt::format(u8"\\u{:04X}", c); result += fmt::format("\\u{:04X}", c);
} else { } else {
result += fmt::format(u8"\\u{:08X}", c); result += fmt::format("\\u{:08X}", c);
} }
} else { } else {
utfcpp::append(static_cast<char32_t>(c), result); utfcpp::append(static_cast<char32_t>(c), result);
@ -150,30 +150,30 @@ std::string EscapeMultilineBasicString(const std::string_view view) {
} }
for (int i = 0; i < quote_run; ++i) { for (int i = 0; i < quote_run; ++i) {
if ((i % 3) == 2) { if ((i % 3) == 2) {
result += u8"\\"; result += "\\";
} }
result += u8"\""; result += "\"";
} }
quote_run = 0; quote_run = 0;
} }
if (c == '\b') { if (c == '\b') {
result += u8"\\b"; result += "\\b";
} else if (c == '\t' || c == '\n') { } else if (c == '\t' || c == '\n') {
result += c; result += c;
} else if (c == '\f') { } else if (c == '\f') {
result += u8"\\f"; result += "\\f";
} else if (c == '\r') { } else if (c == '\r') {
// Silently drop \r. // Silently drop \r.
// result += c; // result += c;
} else if (c == '"') { } else if (c == '"') {
quote_run = 1; quote_run = 1;
} else if (c == '\\') { } else if (c == '\\') {
result += u8"\\\\"; result += "\\\\";
} else if (c < 0x20 || c == 0x7F) { } else if (c < 0x20 || c == 0x7F) {
if (c <= 0xFFFF) { if (c <= 0xFFFF) {
result += fmt::format(u8"\\u{:04X}", c); result += fmt::format("\\u{:04X}", c);
} else { } else {
result += fmt::format(u8"\\u{:08X}", c); result += fmt::format("\\u{:08X}", c);
} }
} else { } else {
utfcpp::append(static_cast<char32_t>(c), result); utfcpp::append(static_cast<char32_t>(c), result);
@ -181,9 +181,9 @@ std::string EscapeMultilineBasicString(const std::string_view view) {
} }
for (int i = 0; i < quote_run; ++i) { for (int i = 0; i < quote_run; ++i) {
if ((i % 3) == 2) { if ((i % 3) == 2) {
result += u8"\\"; result += "\\";
} }
result += u8"\""; result += "\"";
} }
return result; return result;
} }
@ -207,11 +207,11 @@ std::string EscapeString(const std::string_view view) {
} else { } else {
// multi line // multi line
if (xe::utf8::find_any_of(view, escape_chars) == std::string_view::npos && if (xe::utf8::find_any_of(view, escape_chars) == std::string_view::npos &&
xe::utf8::find_first_of(view, u8"'''") == std::string_view::npos) { xe::utf8::find_first_of(view, "'''") == std::string_view::npos) {
return "'''\n" + std::string(view) + "'''"; return "'''\n" + std::string(view) + "'''";
} else { } else {
return u8"\"\"\"\n" + toml_internal::EscapeMultilineBasicString(view) + return "\"\"\"\n" + toml_internal::EscapeMultilineBasicString(view) +
u8"\"\"\""; "\"\"\"";
} }
} }
} }

View File

@ -99,10 +99,11 @@ void AppendLogLine(LogLevel log_level, const char prefix_char, size_t written);
// might as well be noalias // might as well be noalias
template <typename... Args> template <typename... Args>
XE_NOALIAS XE_NOINLINE XE_COLD static void AppendLogLineFormat_Impl( XE_NOALIAS XE_NOINLINE XE_COLD static void AppendLogLineFormat_Impl(
LogLevel log_level, const char prefix_char, const char* format, LogLevel log_level, const char prefix_char, std::string_view format,
const Args&... args) { const Args&... args) noexcept {
auto target = internal::GetThreadBuffer(); auto target = internal::GetThreadBuffer();
auto result = fmt::format_to_n(target.first, target.second, format, args...); auto result = fmt::format_to_n(target.first, target.second,
fmt::runtime(format), args...);
internal::AppendLogLine(log_level, prefix_char, result.size); internal::AppendLogLine(log_level, prefix_char, result.size);
} }
@ -113,8 +114,8 @@ template <typename... Args>
XE_FORCEINLINE static void AppendLogLineFormat(uint32_t log_src_mask, XE_FORCEINLINE static void AppendLogLineFormat(uint32_t log_src_mask,
LogLevel log_level, LogLevel log_level,
const char prefix_char, const char prefix_char,
const char* format, std::string_view format,
const Args&... args) { const Args&... args) noexcept {
if (!internal::ShouldLog(log_level, log_src_mask)) { if (!internal::ShouldLog(log_level, log_src_mask)) {
return; return;
} }
@ -143,7 +144,8 @@ struct LoggerBatch {
LoggerBatch() { reset(); } LoggerBatch() { reset(); }
template <size_t fmtlen, typename... Ts> template <size_t fmtlen, typename... Ts>
void operator()(const char (&fmt)[fmtlen], Ts&&... args) { void operator()(const char (&fmt)[fmtlen], Ts&&... args) {
auto tmpres = fmt::format_to_n(thrd_buf, thrd_buf_rem, fmt, args...); auto tmpres =
fmt::format_to_n(thrd_buf, thrd_buf_rem, fmt::runtime(fmt), args...);
thrd_buf_rem -= tmpres.size; thrd_buf_rem -= tmpres.size;
thrd_buf = tmpres.out; thrd_buf = tmpres.out;
total_size += tmpres.size; total_size += tmpres.size;
@ -164,55 +166,55 @@ struct LoggerBatch {
#if XE_OPTION_ENABLE_LOGGING #if XE_OPTION_ENABLE_LOGGING
template <typename... Args> template <typename... Args>
XE_COLD void XELOGE(const char* format, const Args&... args) { XE_COLD void XELOGE(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized, xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized,
xe::LogLevel::Error, '!', format, args...); xe::LogLevel::Error, '!', format, args...);
} }
template <typename... Args> template <typename... Args>
XE_COLD void XELOGW(const char* format, const Args&... args) { XE_COLD void XELOGW(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized, xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized,
xe::LogLevel::Warning, 'w', format, args...); xe::LogLevel::Warning, 'w', format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGI(const char* format, const Args&... args) { void XELOGI(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized, xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized,
xe::LogLevel::Info, 'i', format, args...); xe::LogLevel::Info, 'i', format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGD(const char* format, const Args&... args) { void XELOGD(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized, xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized,
xe::LogLevel::Debug, 'd', format, args...); xe::LogLevel::Debug, 'd', format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGCPU(const char* format, const Args&... args) { void XELOGCPU(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Cpu, xe::LogLevel::Info, 'C', xe::logging::AppendLogLineFormat(xe::LogSrc::Cpu, xe::LogLevel::Info, 'C',
format, args...); format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGAPU(const char* format, const Args&... args) { void XELOGAPU(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Apu, xe::LogLevel::Debug, 'A', xe::logging::AppendLogLineFormat(xe::LogSrc::Apu, xe::LogLevel::Debug, 'A',
format, args...); format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGGPU(const char* format, const Args&... args) { void XELOGGPU(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized, xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized,
xe::LogLevel::Debug, 'G', format, args...); xe::LogLevel::Debug, 'G', format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGKERNEL(const char* format, const Args&... args) { void XELOGKERNEL(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Kernel, xe::LogLevel::Info, 'K', xe::logging::AppendLogLineFormat(xe::LogSrc::Kernel, xe::LogLevel::Info, 'K',
format, args...); format, args...);
} }
template <typename... Args> template <typename... Args>
void XELOGFS(const char* format, const Args&... args) { void XELOGFS(std::string_view format, const Args&... args) {
xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized, xe::logging::AppendLogLineFormat(xe::LogSrc::Uncategorized,
xe::LogLevel::Info, 'F', format, args...); xe::LogLevel::Info, 'F', format, args...);
} }

View File

@ -193,7 +193,7 @@ std::unique_ptr<Socket> Socket::Connect(std::string hostname, uint16_t port) {
InitializeWinsock(); InitializeWinsock();
auto socket = std::make_unique<Win32Socket>(); auto socket = std::make_unique<Win32Socket>();
if (!socket->Connect(std::move(hostname), port)) { if (!socket->Connect(hostname, port)) {
return nullptr; return nullptr;
} }
return std::unique_ptr<Socket>(socket.release()); return std::unique_ptr<Socket>(socket.release());

View File

@ -35,7 +35,7 @@ class StringBuffer {
template <typename... Args> template <typename... Args>
void AppendFormat(const char* format, const Args&... args) { void AppendFormat(const char* format, const Args&... args) {
auto s = fmt::format(format, args...); auto s = fmt::format(fmt::runtime(format), args...);
Append(s.c_str()); Append(s.c_str());
} }

View File

@ -37,121 +37,121 @@ namespace examples {
const size_t kDanishCount = 1; const size_t kDanishCount = 1;
const char* kDanishValues[kDanishCount] = { const char* kDanishValues[kDanishCount] = {
u8"Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther " "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther "
u8"spillede på xylofon.", "spillede på xylofon.",
}; };
#define TEST_LANGUAGE_EXAMPLES_Danish(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Danish(func, results) \
TEST_EXAMPLES_1(func, Danish, results) TEST_EXAMPLES_1(func, Danish, results)
const size_t kGermanCount = 3; const size_t kGermanCount = 3;
const char* kGermanValues[kGermanCount] = { const char* kGermanValues[kGermanCount] = {
u8"Falsches Üben von Xylophonmusik quält jeden größeren Zwerg", "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg",
u8"Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich", "Zwölf Boxkämpfer jagten Eva quer über den Sylter Deich",
u8"Heizölrückstoßabdämpfung", "Heizölrückstoßabdämpfung",
}; };
#define TEST_LANGUAGE_EXAMPLES_German(func, results) \ #define TEST_LANGUAGE_EXAMPLES_German(func, results) \
TEST_EXAMPLES_2(func, German, results) TEST_EXAMPLES_2(func, German, results)
const size_t kGreekCount = 2; const size_t kGreekCount = 2;
const char* kGreekValues[kGreekCount] = { const char* kGreekValues[kGreekCount] = {
u8"Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο", "Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο",
u8"Ξεσκεπάζω τὴν ψυχοφθόρα βδελυγμία", "Ξεσκεπάζω τὴν ψυχοφθόρα βδελυγμία",
}; };
#define TEST_LANGUAGE_EXAMPLES_Greek(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Greek(func, results) \
TEST_EXAMPLES_2(func, Greek, results) TEST_EXAMPLES_2(func, Greek, results)
const size_t kEnglishCount = 1; const size_t kEnglishCount = 1;
const char* kEnglishValues[kEnglishCount] = { const char* kEnglishValues[kEnglishCount] = {
u8"The quick brown fox jumps over the lazy dog", "The quick brown fox jumps over the lazy dog",
}; };
#define TEST_LANGUAGE_EXAMPLES_English(func, results) \ #define TEST_LANGUAGE_EXAMPLES_English(func, results) \
TEST_EXAMPLES_1(func, English, results) TEST_EXAMPLES_1(func, English, results)
const size_t kSpanishCount = 1; const size_t kSpanishCount = 1;
const char* kSpanishValues[kSpanishCount] = { const char* kSpanishValues[kSpanishCount] = {
u8"El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, " "El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, "
u8"añoraba a su querido cachorro.", "añoraba a su querido cachorro.",
}; };
#define TEST_LANGUAGE_EXAMPLES_Spanish(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Spanish(func, results) \
TEST_EXAMPLES_1(func, Spanish, results) TEST_EXAMPLES_1(func, Spanish, results)
const size_t kFrenchCount = 3; const size_t kFrenchCount = 3;
const char* kFrenchValues[kFrenchCount] = { const char* kFrenchValues[kFrenchCount] = {
u8"Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à " "Portez ce vieux whisky au juge blond qui fume sur son île intérieure, à "
u8"côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce qui " "côté de l'alcôve ovoïde, où les bûches se consument dans l'âtre, ce qui "
u8"lui permet de penser à la cænogenèse de l'être dont il est question " "lui permet de penser à la cænogenèse de l'être dont il est question "
u8"dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, " "dans la cause ambiguë entendue à Moÿ, dans un capharnaüm qui, "
u8"pense-t-il, diminue çà et là la qualité de son œuvre.", "pense-t-il, diminue çà et là la qualité de son œuvre.",
u8"l'île exiguë\n" "l'île exiguë\n"
u8"Où l'obèse jury mûr\n" "Où l'obèse jury mûr\n"
u8"Fête l'haï volapük,\n" "Fête l'haï volapük,\n"
u8"Âne ex aéquo au whist,\n" "Âne ex aéquo au whist,\n"
u8"Ôtez ce vœu déçu.", "Ôtez ce vœu déçu.",
u8"Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë " "Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë "
u8"au delà des îles, près du mälström où brûlent les novæ.", "au delà des îles, près du mälström où brûlent les novæ.",
}; };
#define TEST_LANGUAGE_EXAMPLES_French(func, results) \ #define TEST_LANGUAGE_EXAMPLES_French(func, results) \
TEST_EXAMPLES_3(func, French, results) TEST_EXAMPLES_3(func, French, results)
const size_t kIrishGaelicCount = 1; const size_t kIrishGaelicCount = 1;
const char* kIrishGaelicValues[kIrishGaelicCount] = { const char* kIrishGaelicValues[kIrishGaelicCount] = {
u8"D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh", "D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh",
}; };
#define TEST_LANGUAGE_EXAMPLES_IrishGaelic(func, results) \ #define TEST_LANGUAGE_EXAMPLES_IrishGaelic(func, results) \
TEST_EXAMPLES_1(func, IrishGaelic, results) TEST_EXAMPLES_1(func, IrishGaelic, results)
const size_t kHungarianCount = 1; const size_t kHungarianCount = 1;
const char* kHungarianValues[kHungarianCount] = { const char* kHungarianValues[kHungarianCount] = {
u8"Árvíztűrő tükörfúrógép", "Árvíztűrő tükörfúrógép",
}; };
#define TEST_LANGUAGE_EXAMPLES_Hungarian(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Hungarian(func, results) \
TEST_EXAMPLES_1(func, Hungarian, results) TEST_EXAMPLES_1(func, Hungarian, results)
const size_t kIcelandicCount = 2; const size_t kIcelandicCount = 2;
const char* kIcelandicValues[kIcelandicCount] = { const char* kIcelandicValues[kIcelandicCount] = {
u8"Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa", "Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa",
u8"Sævör grét áðan því úlpan var ónýt", "Sævör grét áðan því úlpan var ónýt",
}; };
#define TEST_LANGUAGE_EXAMPLES_Icelandic(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Icelandic(func, results) \
TEST_EXAMPLES_2(func, Icelandic, results) TEST_EXAMPLES_2(func, Icelandic, results)
const size_t kJapaneseCount = 2; const size_t kJapaneseCount = 2;
const char* kJapaneseValues[kJapaneseCount] = { const char* kJapaneseValues[kJapaneseCount] = {
u8"いろはにほへとちりぬるを\n" "いろはにほへとちりぬるを\n"
u8"わかよたれそつねならむ\n" "わかよたれそつねならむ\n"
u8"うゐのおくやまけふこえて\n" "うゐのおくやまけふこえて\n"
u8"あさきゆめみしゑひもせす\n", "あさきゆめみしゑひもせす\n",
u8"イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム\n" "イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム\n"
u8"ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン",
}; };
#define TEST_LANGUAGE_EXAMPLES_Japanese(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Japanese(func, results) \
TEST_EXAMPLES_2(func, Japanese, results) TEST_EXAMPLES_2(func, Japanese, results)
const size_t kHebrewCount = 1; const size_t kHebrewCount = 1;
const char* kHebrewValues[kHebrewCount] = { const char* kHebrewValues[kHebrewCount] = {
u8"? דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה", "? דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה",
}; };
#define TEST_LANGUAGE_EXAMPLES_Hebrew(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Hebrew(func, results) \
TEST_EXAMPLES_1(func, Hebrew, results) TEST_EXAMPLES_1(func, Hebrew, results)
const size_t kPolishCount = 1; const size_t kPolishCount = 1;
const char* kPolishValues[kPolishCount] = { const char* kPolishValues[kPolishCount] = {
u8"Pchnąć w tę łódź jeża lub ośm skrzyń fig", "Pchnąć w tę łódź jeża lub ośm skrzyń fig",
}; };
#define TEST_LANGUAGE_EXAMPLES_Polish(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Polish(func, results) \
TEST_EXAMPLES_1(func, Polish, results) TEST_EXAMPLES_1(func, Polish, results)
const size_t kRussianCount = 2; const size_t kRussianCount = 2;
const char* kRussianValues[kRussianCount] = { const char* kRussianValues[kRussianCount] = {
u8"В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!", "В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!",
u8"Съешь же ещё этих мягких французских булок да выпей чаю", "Съешь же ещё этих мягких французских булок да выпей чаю",
}; };
#define TEST_LANGUAGE_EXAMPLES_Russian(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Russian(func, results) \
TEST_EXAMPLES_2(func, Russian, results) TEST_EXAMPLES_2(func, Russian, results)
const size_t kTurkishCount = 1; const size_t kTurkishCount = 1;
const char* kTurkishValues[kTurkishCount] = { const char* kTurkishValues[kTurkishCount] = {
u8"Pijamalı hasta, yağız şoföre çabucak güvendi.", "Pijamalı hasta, yağız şoföre çabucak güvendi.",
}; };
#define TEST_LANGUAGE_EXAMPLES_Turkish(func, results) \ #define TEST_LANGUAGE_EXAMPLES_Turkish(func, results) \
TEST_EXAMPLES_1(func, Turkish, results) TEST_EXAMPLES_1(func, Turkish, results)
@ -229,54 +229,54 @@ TEST_CASE("UTF-8 Split", "[utf8]") {
std::vector<std::string_view> parts; std::vector<std::string_view> parts;
// Danish // Danish
parts = utf8::split(examples::kDanishValues[0], u8"æcå"); parts = utf8::split(examples::kDanishValues[0], "æcå");
REQUIRE(parts.size() == 4); REQUIRE(parts.size() == 4);
REQUIRE(parts[0] == u8"Quizdeltagerne spiste jordb"); REQUIRE(parts[0] == "Quizdeltagerne spiste jordb");
REQUIRE(parts[1] == u8"r med fløde, mens "); REQUIRE(parts[1] == "r med fløde, mens ");
REQUIRE(parts[2] == u8"irkusklovnen Wolther spillede p"); REQUIRE(parts[2] == "irkusklovnen Wolther spillede p");
REQUIRE(parts[3] == u8" xylofon."); REQUIRE(parts[3] == " xylofon.");
// German // German
parts = utf8::split(examples::kGermanValues[0], u8"ßS"); parts = utf8::split(examples::kGermanValues[0], "ßS");
REQUIRE(parts.size() == 2); REQUIRE(parts.size() == 2);
REQUIRE(parts[0] == u8"Falsches Üben von Xylophonmusik quält jeden grö"); REQUIRE(parts[0] == "Falsches Üben von Xylophonmusik quält jeden grö");
REQUIRE(parts[1] == u8"eren Zwerg"); REQUIRE(parts[1] == "eren Zwerg");
parts = utf8::split(examples::kGermanValues[1], u8"ßS"); parts = utf8::split(examples::kGermanValues[1], "ßS");
REQUIRE(parts.size() == 2); REQUIRE(parts.size() == 2);
REQUIRE(parts[0] == u8"Zwölf Boxkämpfer jagten Eva quer über den "); REQUIRE(parts[0] == "Zwölf Boxkämpfer jagten Eva quer über den ");
REQUIRE(parts[1] == u8"ylter Deich"); REQUIRE(parts[1] == "ylter Deich");
parts = utf8::split(examples::kGermanValues[2], u8"ßS"); parts = utf8::split(examples::kGermanValues[2], "ßS");
REQUIRE(parts.size() == 2); REQUIRE(parts.size() == 2);
REQUIRE(parts[0] == u8"Heizölrücksto"); REQUIRE(parts[0] == "Heizölrücksto");
REQUIRE(parts[1] == u8"abdämpfung"); REQUIRE(parts[1] == "abdämpfung");
// Greek // Greek
parts = utf8::split(examples::kGreekValues[0], u8"πφ"); parts = utf8::split(examples::kGreekValues[0], "πφ");
REQUIRE(parts.size() == 4); REQUIRE(parts.size() == 4);
REQUIRE(parts[0] == u8"Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ "); REQUIRE(parts[0] == "Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ ");
REQUIRE(parts[1] == u8"ιὰ στὸ χρυσα"); REQUIRE(parts[1] == "ιὰ στὸ χρυσα");
REQUIRE(parts[2] == u8"ὶ ξέ"); REQUIRE(parts[2] == "ὶ ξέ");
REQUIRE(parts[3] == u8"ωτο"); REQUIRE(parts[3] == "ωτο");
parts = utf8::split(examples::kGreekValues[1], u8"πφ"); parts = utf8::split(examples::kGreekValues[1], "πφ");
REQUIRE(parts.size() == 3); REQUIRE(parts.size() == 3);
REQUIRE(parts[0] == u8"Ξεσκε"); REQUIRE(parts[0] == "Ξεσκε");
REQUIRE(parts[1] == u8"άζω τὴν ψυχο"); REQUIRE(parts[1] == "άζω τὴν ψυχο");
REQUIRE(parts[2] == u8"θόρα βδελυγμία"); REQUIRE(parts[2] == "θόρα βδελυγμία");
// English // English
parts = utf8::split(examples::kEnglishValues[0], "xy"); parts = utf8::split(examples::kEnglishValues[0], "xy");
REQUIRE(parts.size() == 3); REQUIRE(parts.size() == 3);
REQUIRE(parts[0] == u8"The quick brown fo"); REQUIRE(parts[0] == "The quick brown fo");
REQUIRE(parts[1] == u8" jumps over the laz"); REQUIRE(parts[1] == " jumps over the laz");
REQUIRE(parts[2] == u8" dog"); REQUIRE(parts[2] == " dog");
// Spanish // Spanish
parts = utf8::split(examples::kSpanishValues[0], u8"ójd"); parts = utf8::split(examples::kSpanishValues[0], "ójd");
REQUIRE(parts.size() == 4); REQUIRE(parts.size() == 4);
REQUIRE(parts[0] == u8"El pingüino Wenceslao hizo kil"); REQUIRE(parts[0] == "El pingüino Wenceslao hizo kil");
REQUIRE(parts[1] == u8"metros ba"); REQUIRE(parts[1] == "metros ba");
REQUIRE(parts[2] == u8"o exhaustiva lluvia y frío, añoraba a su queri"); REQUIRE(parts[2] == "o exhaustiva lluvia y frío, añoraba a su queri");
REQUIRE(parts[3] == u8"o cachorro."); REQUIRE(parts[3] == "o cachorro.");
// TODO(gibbed): French // TODO(gibbed): French
// TODO(gibbed): Irish Gaelic // TODO(gibbed): Irish Gaelic
@ -291,18 +291,18 @@ TEST_CASE("UTF-8 Split", "[utf8]") {
} }
TEST_CASE("UTF-8 Equal Z", "[utf8]") { TEST_CASE("UTF-8 Equal Z", "[utf8]") {
REQUIRE(utf8::equal_z(u8"foo", u8"foo\0")); REQUIRE(utf8::equal_z("foo", "foo\0"));
REQUIRE_FALSE(utf8::equal_z(u8"bar", u8"baz\0")); REQUIRE_FALSE(utf8::equal_z("bar", "baz\0"));
} }
TEST_CASE("UTF-8 Equal Case", "[utf8]") { TEST_CASE("UTF-8 Equal Case", "[utf8]") {
REQUIRE(utf8::equal_case(u8"foo", u8"foo\0")); REQUIRE(utf8::equal_case("foo", "foo\0"));
REQUIRE_FALSE(utf8::equal_case(u8"bar", u8"baz\0")); REQUIRE_FALSE(utf8::equal_case("bar", "baz\0"));
} }
TEST_CASE("UTF-8 Equal Case Z", "[utf8]") { TEST_CASE("UTF-8 Equal Case Z", "[utf8]") {
REQUIRE(utf8::equal_case_z(u8"foo", u8"foo\0")); REQUIRE(utf8::equal_case_z("foo", "foo\0"));
REQUIRE_FALSE(utf8::equal_case_z(u8"bar", u8"baz\0")); REQUIRE_FALSE(utf8::equal_case_z("bar", "baz\0"));
} }
// TODO(gibbed): find_any_of // TODO(gibbed): find_any_of
@ -346,11 +346,11 @@ TEST_CASE("UTF-8 Equal Case Z", "[utf8]") {
} while (0) } while (0)
TEST_CASE("UTF-8 Join Paths", "[utf8]") { TEST_CASE("UTF-8 Join Paths", "[utf8]") {
TEST_PATHS(utf8::join_paths, u8""); TEST_PATHS(utf8::join_paths, "");
TEST_PATHS(utf8::join_paths, u8"foo", u8"foo"); TEST_PATHS(utf8::join_paths, "foo", "foo");
TEST_PATHS(utf8::join_paths, u8"foo/bar", u8"foo", u8"bar"); TEST_PATHS(utf8::join_paths, "foo/bar", "foo", "bar");
TEST_PATHS(utf8::join_paths, "X:/foo/bar/baz/qux", u8"X:", u8"foo", u8"bar", TEST_PATHS(utf8::join_paths, "X:/foo/bar/baz/qux", "X:", "foo", "bar", "baz",
u8"baz", u8"qux"); "qux");
} }
// TODO(gibbed): join_guest_paths // TODO(gibbed): join_guest_paths

View File

@ -469,7 +469,7 @@ bool ends_with_case(const std::string_view haystack,
} }
std::vector<std::string_view> split_path(const std::string_view path) { std::vector<std::string_view> split_path(const std::string_view path) {
return split(path, u8"\\/", true); return split(path, "\\/", true);
} }
std::string join_paths(const std::string_view left_path, std::string join_paths(const std::string_view left_path,

View File

@ -99,7 +99,8 @@ class HIRBuilder {
void CommentFormat(const std::string_view format, const Args&... args) { void CommentFormat(const std::string_view format, const Args&... args) {
static const uint32_t kMaxCommentSize = 1024; static const uint32_t kMaxCommentSize = 1024;
char* p = reinterpret_cast<char*>(arena_->Alloc(kMaxCommentSize, 1)); char* p = reinterpret_cast<char*>(arena_->Alloc(kMaxCommentSize, 1));
auto result = fmt::format_to_n(p, kMaxCommentSize - 1, format, args...); auto result =
fmt::format_to_n(p, kMaxCommentSize - 1, fmt::runtime(format), args...);
p[result.size] = '\0'; p[result.size] = '\0';
size_t rewind = kMaxCommentSize - 1 - result.size; size_t rewind = kMaxCommentSize - 1 - result.size;
arena_->Rewind(rewind); arena_->Rewind(rewind);

View File

@ -155,7 +155,7 @@ void PPCTranslator::DumpHIR(GuestFunction* function, PPCHIRBuilder* builder) {
folder_path.append(&tmpbuf[0]); folder_path.append(&tmpbuf[0]);
} }
FILE* f = fopen(folder_path.generic_u8string().c_str(), "w"); FILE* f = fopen(folder_path.string().c_str(), "w");
if (f) { if (f) {
fputs(buffer.buffer(), f); fputs(buffer.buffer(), f);
fclose(f); fclose(f);

View File

@ -718,7 +718,7 @@ X_STATUS Emulator::DataMigration(const uint64_t xuid) {
const auto old_profile_data = const auto old_profile_data =
xe::filesystem::ListDirectories(title.path / title.name / "profile"); xe::filesystem::ListDirectories(title.path / title.name / "profile");
xe::filesystem::FileInfo& entry_to_copy = xe::filesystem::FileInfo(); xe::filesystem::FileInfo entry_to_copy = xe::filesystem::FileInfo();
if (old_profile_data.size() != 1) { if (old_profile_data.size() != 1) {
for (const auto& entry : old_profile_data) { for (const auto& entry : old_profile_data) {
if (entry.name == "User") { if (entry.name == "User") {

View File

@ -245,8 +245,7 @@ class Emulator {
ContentInstallationInfo& installation_info); ContentInstallationInfo& installation_info);
// Extract content of zar package to desired directory. // Extract content of zar package to desired directory.
X_STATUS Emulator::ExtractZarchivePackage( X_STATUS ExtractZarchivePackage(const std::filesystem::path& path,
const std::filesystem::path& path,
const std::filesystem::path& extract_dir); const std::filesystem::path& extract_dir);
// Pack contents of a folder into a zar package. // Pack contents of a folder into a zar package.

View File

@ -383,7 +383,7 @@ struct GetViewportInfoArgs {
depth_format = regs.Get<reg::RB_DEPTH_INFO>().depth_format; depth_format = regs.Get<reg::RB_DEPTH_INFO>().depth_format;
} }
XE_FORCEINLINE XE_FORCEINLINE
bool operator==(const GetViewportInfoArgs& prev) { bool operator==(const GetViewportInfoArgs& prev) const {
#if XE_ARCH_AMD64 == 0 #if XE_ARCH_AMD64 == 0
bool result = true; bool result = true;

View File

@ -94,9 +94,9 @@ void TextureDump(const TextureInfo& src, void* buffer, size_t length) {
static int dump_counter = 0; static int dump_counter = 0;
std::filesystem::path path = "texture_dumps"; std::filesystem::path path = "texture_dumps";
path /= fmt::format("{:05d}_{:08X}_{:08X}_{:08X}.dds", dump_counter++, path /= fmt::format(fmt::runtime("{:05d}_{:08X}_{:08X}_{:08X}.dds"),
src.memory.base_address, src.memory.mip_address, dump_counter++, src.memory.base_address,
src.format_name()); src.memory.mip_address, src.format_name());
FILE* handle = filesystem::OpenFile(path, "wb"); FILE* handle = filesystem::OpenFile(path, "wb");
if (handle) { if (handle) {

View File

@ -64,7 +64,7 @@ TraceViewer::TraceViewer(xe::ui::WindowedAppContext& app_context,
TraceViewer::~TraceViewer() = default; TraceViewer::~TraceViewer() = default;
bool TraceViewer::OnInitialize() { bool TraceViewer::OnInitialize() {
std::string path = cvars::target_trace_file.u8string(); std::string path = cvars::target_trace_file.string();
// If no path passed, ask the user. // If no path passed, ask the user.
// On Android, however, there's no synchronous file picker, and the trace file // On Android, however, there's no synchronous file picker, and the trace file

View File

@ -155,7 +155,7 @@ void SDLInputDriver::LoadGameControllerDB() {
std::string guid = row[0]; std::string guid = row[0];
std::string controller_name = row[1]; std::string controller_name = row[1];
auto format = [](std::string& ss, std::string& s) { auto format = [](std::string ss, const std::string& s) {
return ss.empty() ? s : ss + "," + s; return ss.empty() ? s : ss + "," + s;
}; };

View File

@ -103,7 +103,8 @@ std::filesystem::path ContentManager::ResolvePackagePath(
// Content path: // Content path:
// content_root/title_id/content_type/data_file_name/ // content_root/title_id/content_type/data_file_name/
auto get_package_path = [&, data, disc_number](const uint32_t title_id) { auto get_package_path = [&, data, disc_number](const uint32_t title_id) {
uint64_t used_xuid = (data.xuid != -1 && data.xuid != 0) ? data.xuid : xuid; uint64_t used_xuid =
(data.xuid != -1 && data.xuid != 0) ? data.xuid.get() : xuid;
auto package_root = auto package_root =
ResolvePackageRoot(used_xuid, title_id, data.content_type); ResolvePackageRoot(used_xuid, title_id, data.content_type);
@ -263,7 +264,8 @@ X_RESULT ContentManager::WriteContentHeaderFile(const uint64_t xuid,
if (data.xuid == -1) { if (data.xuid == -1) {
data.xuid = xuid; data.xuid = xuid;
} }
uint64_t used_xuid = (data.xuid != -1 && data.xuid != 0) ? data.xuid : xuid; uint64_t used_xuid =
(data.xuid != -1 && data.xuid != 0) ? data.xuid.get() : xuid;
auto header_path = ResolvePackageHeaderPath(data.file_name(), used_xuid, auto header_path = ResolvePackageHeaderPath(data.file_name(), used_xuid,
data.title_id, data.content_type); data.title_id, data.content_type);

View File

@ -621,8 +621,8 @@ DECLARE_XAM_EXPORT1(XamLoaderGetMediaInfoEx, kContent, kStub);
dword_result_t XamContentLaunchImageFromFileInternal_entry( dword_result_t XamContentLaunchImageFromFileInternal_entry(
lpstring_t image_location, lpstring_t xex_name, dword_t unk) { lpstring_t image_location, lpstring_t xex_name, dword_t unk) {
const std::string image_path = image_location; const std::string image_path = static_cast<std::string>(image_location);
const std::string xex_name_ = xex_name; const std::string xex_name_ = static_cast<std::string>(xex_name);
vfs::Entry* entry = kernel_state()->file_system()->ResolvePath(image_path); vfs::Entry* entry = kernel_state()->file_system()->ResolvePath(image_path);

View File

@ -115,8 +115,9 @@ dword_result_t XamContentAggregateCreateEnumerator_entry(qword_t xuid,
for (auto& title_id : title_ids) { for (auto& title_id : title_ids) {
// Get all content data. // Get all content data.
auto content_datas = kernel_state()->content_manager()->ListContent( auto content_datas = kernel_state()->content_manager()->ListContent(
static_cast<uint32_t>(DummyDeviceId::HDD), xuid == -1 ? 0 : xuid, static_cast<uint32_t>(DummyDeviceId::HDD),
title_id, content_type_enum); xuid == -1 ? 0 : static_cast<uint64_t>(xuid), title_id,
content_type_enum);
for (const auto& content_data : content_datas) { for (const auto& content_data : content_datas) {
auto item = e->AppendItem(); auto item = e->AppendItem();
assert_not_null(item); assert_not_null(item);

View File

@ -111,14 +111,14 @@ void XamModule::SaveLoaderData() {
std::filesystem::path host_path = loader_data_.host_path; std::filesystem::path host_path = loader_data_.host_path;
std::string launch_path = loader_data_.launch_path; std::string launch_path = loader_data_.launch_path;
auto remove_prefix = [&launch_path](std::string& prefix) { auto remove_prefix = [&launch_path](std::string_view prefix) {
if (launch_path.compare(0, prefix.length(), prefix) == 0) { if (launch_path.compare(0, prefix.length(), prefix) == 0) {
launch_path = launch_path.substr(prefix.length()); launch_path = launch_path.substr(prefix.length());
} }
}; };
remove_prefix(std::string("game:\\")); remove_prefix("game:\\");
remove_prefix(std::string("d:\\")); remove_prefix("d:\\");
if (host_path.extension() == ".xex") { if (host_path.extension() == ".xex") {
host_path.remove_filename(); host_path.remove_filename();

View File

@ -829,9 +829,11 @@ static dword_result_t XamShowMessageBoxUi(
}; };
const Emulator* emulator = kernel_state()->emulator(); const Emulator* emulator = kernel_state()->emulator();
ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer();
auto text = xe::to_utf8(text_ptr.value());
result = xeXamDispatchDialog<MessageBoxDialog>( result = xeXamDispatchDialog<MessageBoxDialog>(
new MessageBoxDialog(imgui_drawer, title, xe::to_utf8(text_ptr.value()), new MessageBoxDialog(imgui_drawer, title, text, buttons,
buttons, active_button), static_cast<uint32_t>(active_button)),
close, overlapped); close, overlapped);
} }
return result; return result;
@ -1012,11 +1014,14 @@ dword_result_t XamShowKeyboardUI_entry(
}; };
const Emulator* emulator = kernel_state()->emulator(); const Emulator* emulator = kernel_state()->emulator();
ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer(); ui::ImGuiDrawer* imgui_drawer = emulator->imgui_drawer();
std::string title_str = title ? xe::to_utf8(title.value()) : "";
std::string desc_str = description ? xe::to_utf8(description.value()) : "";
std::string def_text_str =
default_text ? xe::to_utf8(default_text.value()) : "";
result = xeXamDispatchDialogEx<KeyboardInputDialog>( result = xeXamDispatchDialogEx<KeyboardInputDialog>(
new KeyboardInputDialog( new KeyboardInputDialog(imgui_drawer, title_str, desc_str, def_text_str,
imgui_drawer, title ? xe::to_utf8(title.value()) : "",
description ? xe::to_utf8(description.value()) : "",
default_text ? xe::to_utf8(default_text.value()) : "",
buffer_length), buffer_length),
close, overlapped); close, overlapped);
} }

View File

@ -620,7 +620,8 @@ dword_result_t XamUserCreateAchievementEnumerator_entry(
} }
const util::XdbfGameData db = kernel_state()->title_xdbf(); const util::XdbfGameData db = kernel_state()->title_xdbf();
uint32_t title_id_ = title_id ? title_id : kernel_state()->title_id(); uint32_t title_id_ =
title_id ? static_cast<uint32_t>(title_id) : kernel_state()->title_id();
const auto user_title_achievements = const auto user_title_achievements =
kernel_state()->achievement_manager()->GetTitleAchievements( kernel_state()->achievement_manager()->GetTitleAchievements(

View File

@ -354,7 +354,7 @@ dword_result_t ObCreateSymbolicLink_entry(pointer_t<X_ANSI_STRING> path_ptr,
auto target = xe::utf8::canonicalize_guest_path( auto target = xe::utf8::canonicalize_guest_path(
util::TranslateAnsiString(kernel_memory(), target_ptr)); util::TranslateAnsiString(kernel_memory(), target_ptr));
if (xe::utf8::starts_with(path, u8"\\??\\")) { if (xe::utf8::starts_with(path, "\\??\\")) {
path = path.substr(4); // Strip the full qualifier path = path.substr(4); // Strip the full qualifier
} }

View File

@ -349,7 +349,9 @@ class object_ref {
void reset(T* value) noexcept { object_ref(value).swap(*this); } void reset(T* value) noexcept { object_ref(value).swap(*this); }
inline bool operator==(const T* right) noexcept { return value_ == right; } inline bool operator==(const T* right) const noexcept {
return value_ == right;
}
private: private:
T* value_ = nullptr; T* value_ = nullptr;