From 1fa6695aea877312ff18aca566f4988894dc07c9 Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Tue, 8 Jul 2025 18:20:13 +0300 Subject: [PATCH] Add translatable text in core code & add API in gui interface for showing error dialogs --- src/Cafe/CafeSystem.cpp | 18 +-- src/Cafe/Filesystem/FST/KeyCache.cpp | 6 +- src/Cafe/GraphicPack/GraphicPack2Patches.cpp | 11 +- .../GraphicPack/GraphicPack2PatchesApply.cpp | 4 +- src/Cafe/GraphicPack/GraphicPackError.h | 2 +- src/Cafe/HW/Latte/Core/LatteShaderCache.cpp | 2 - .../Latte/Renderer/Vulkan/VulkanRenderer.cpp | 2 +- src/Cafe/HW/MMU/MMU.cpp | 7 +- .../Tools/DownloadManager/DownloadManager.cpp | 71 +++++----- .../Tools/DownloadManager/DownloadManager.h | 122 ++---------------- src/Common/precompiled.h | 21 +++ src/config/CemuConfig.h | 18 +-- src/config/LaunchSettings.cpp | 5 +- src/gui/interface/WindowSystem.h | 12 ++ src/gui/wxgui/CemuApp.cpp | 7 + src/gui/wxgui/TitleManager.cpp | 72 +---------- src/gui/wxgui/TitleManager.h | 4 +- .../panels/ClassicControllerInputPanel.cpp | 62 +-------- .../input/panels/ProControllerInputPanel.cpp | 65 +--------- src/gui/wxgui/input/panels/VPADInputPanel.cpp | 62 +-------- .../wxgui/input/panels/WiimoteInputPanel.cpp | 50 +------ src/gui/wxgui/wxWindowSystem.cpp | 12 ++ src/input/emulated/ClassicController.cpp | 26 ++-- src/input/emulated/ProController.cpp | 30 ++--- src/input/emulated/VPADController.cpp | 30 ++--- src/input/emulated/WiimoteController.cpp | 18 +-- src/util/helpers/helpers.cpp | 27 +--- src/util/helpers/helpers.h | 2 - 28 files changed, 206 insertions(+), 562 deletions(-) diff --git a/src/Cafe/CafeSystem.cpp b/src/Cafe/CafeSystem.cpp index b1cc0539..8a2239b0 100644 --- a/src/Cafe/CafeSystem.cpp +++ b/src/Cafe/CafeSystem.cpp @@ -128,7 +128,7 @@ void SetEntryPoint(MPTR entryPoint) } // load executable into virtual memory and set entrypoint -bool LoadMainExecutable() +void LoadMainExecutable() { isLaunchTypeELF = false; // when launching from a disc image _pathToExecutable is initially empty @@ -142,7 +142,6 @@ bool LoadMainExecutable() cemuLog_log(LogType::Force, "Unable to find RPX executable"); cemuLog_waitForFlush(); cemu_assert(false); - return false; } } // extract and load RPX @@ -153,7 +152,6 @@ bool LoadMainExecutable() cemuLog_log(LogType::Force, "Failed to load \"{}\"", _pathToExecutable); cemuLog_waitForFlush(); cemu_assert(false); - return false; } currentUpdatedApplicationHash = generateHashFromRawRPXData(rpxData, rpxSize); // determine if this file is an ELF @@ -171,10 +169,10 @@ bool LoadMainExecutable() applicationRPX = RPLLoader_LoadFromMemory(rpxData, rpxSize, (char*)_pathToExecutable.c_str()); if (!applicationRPX) { - cemuLog_log(LogType::Force, "Failed to run this title because the executable is damaged"); + WindowSystem::showErrorDialog(_tr("Failed to run this title because the executable is damaged")); + cemuLog_createLogFile(false); cemuLog_waitForFlush(); - cemu_assert(false); - return false; + exit(0); } RPLLoader_SetMainModule(applicationRPX); SetEntryPoint(RPLLoader_GetModuleEntrypoint(applicationRPX)); @@ -193,7 +191,6 @@ bool LoadMainExecutable() } free(baseRpxData); debug_printf("RPXHash: 0x%08x\n", currentBaseApplicationHash); - return true; } fs::path getTitleSavePath() @@ -755,12 +752,7 @@ namespace CafeSystem } } } - - if (!LoadMainExecutable()) - { - return PREPARE_STATUS_CODE::INVALID_RPX; - } - + LoadMainExecutable(); return PREPARE_STATUS_CODE::SUCCESS; } diff --git a/src/Cafe/Filesystem/FST/KeyCache.cpp b/src/Cafe/Filesystem/FST/KeyCache.cpp index d0a75b74..4235877d 100644 --- a/src/Cafe/Filesystem/FST/KeyCache.cpp +++ b/src/Cafe/Filesystem/FST/KeyCache.cpp @@ -1,6 +1,7 @@ #include #include "Cemu/Logging/CemuLogging.h" +#include "WindowSystem.h" #include "config/ActiveSettings.h" #include "util/crypto/aes128.h" #include "Common/FileStream.h" @@ -74,7 +75,7 @@ void KeyCache_Prepare() } else { - cemuLog_log(LogType::Force, "Unable to create file keys.txt\nThis can happen if Cemu does not have write permission to its own directory, the disk is full or if anti-virus software is blocking Cemu."); + WindowSystem::showErrorDialog(_tr("Unable to create file keys.txt\nThis can happen if Cemu does not have write permission to its own directory, the disk is full or if anti-virus software is blocking Cemu."), _tr("Error"), WindowSystem::ErrorCategory::KEYS_TXT_CREATION); } mtxKeyCache.unlock(); return; @@ -107,7 +108,8 @@ void KeyCache_Prepare() continue; if( strishex(line) == false ) { - cemuLog_log(LogType::Force, "Error in keys.txt at line {}", lineNumber); + auto errorMsg = fmt::format(fmt::runtime(_tr("Error in keys.txt at line {}")), lineNumber); + WindowSystem::showErrorDialog(errorMsg, WindowSystem::ErrorCategory::KEYS_TXT_CREATION); continue; } if(line.size() == 32 ) diff --git a/src/Cafe/GraphicPack/GraphicPack2Patches.cpp b/src/Cafe/GraphicPack/GraphicPack2Patches.cpp index 7052cc69..0838b1b5 100644 --- a/src/Cafe/GraphicPack/GraphicPack2Patches.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2Patches.cpp @@ -1,6 +1,7 @@ #include "Cafe/GraphicPack/GraphicPack2.h" #include "Cemu/Logging/CemuLogging.h" #include "Common/FileStream.h" +#include "WindowSystem.h" #include "util/helpers/StringParser.h" #include "Cemu/PPCAssembler/ppcAssembler.h" #include "Cafe/OS/RPL/rpl_structs.h" @@ -36,15 +37,15 @@ void PatchErrorHandler::printError(class PatchGroup* patchGroup, sint32 lineNumb errorMessages.emplace_back(msg); } -void PatchErrorHandler::logStageError() +void PatchErrorHandler::showStageErrorMessageBox() { std::string errorMsg; if (m_gp) { if (m_stage == STAGE::PARSER) - errorMsg = fmt::format("Failed to load patches for graphic pack \'{}\'", m_gp->GetName()); + errorMsg.assign(fmt::format(fmt::runtime(_tr("Failed to load patches for graphic pack \'{}\'")), m_gp->GetName())); else - errorMsg = fmt::format("Failed to apply patches for graphic pack \'{}\'", m_gp->GetName()); + errorMsg.assign(fmt::format(fmt::runtime(_tr("Failed to apply patches for graphic pack \'{}\'")), m_gp->GetName())); } else { @@ -53,7 +54,7 @@ void PatchErrorHandler::logStageError() if (cemuLog_isLoggingEnabled(LogType::Patches)) { errorMsg.append("\n \n") - .append("Details:") + .append(_tr("Details:")) .append("\n"); for (auto& itr : errorMessages) { @@ -62,7 +63,7 @@ void PatchErrorHandler::logStageError() } } - cemuLog_log(LogType::Force, errorMsg); + WindowSystem::showErrorDialog(errorMsg, _tr("Graphic pack error"), WindowSystem::ErrorCategory::GRAPHIC_PACKS); } // loads Cemu-style patches (patch_.asm) diff --git a/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp b/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp index 0b134520..b6af542d 100644 --- a/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp @@ -691,13 +691,13 @@ void GraphicPack2::ApplyPatchGroups(std::vector& groups, const RPLM patchContext.errorHandler.printError(nullptr, -1, "Some symbols could not be resolved because the dependency chain is too deep"); for (auto& itr : patchContext.unresolvedSymbols) patchContext.errorHandler.printError(itr.patchGroup, itr.lineNumber, fmt::format("Unresolved symbol: {}", itr.symbolName)); - patchContext.errorHandler.logStageError(); + patchContext.errorHandler.showStageErrorMessageBox(); return; } } if (!isUnresolvedPatchesEmpty() || patchContext.errorHandler.hasError()) { - patchContext.errorHandler.logStageError(); + patchContext.errorHandler.showStageErrorMessageBox(); return; } // apply relocated patches diff --git a/src/Cafe/GraphicPack/GraphicPackError.h b/src/Cafe/GraphicPack/GraphicPackError.h index 04d91161..91cdb130 100644 --- a/src/Cafe/GraphicPack/GraphicPackError.h +++ b/src/Cafe/GraphicPack/GraphicPackError.h @@ -21,7 +21,7 @@ public: } void printError(class PatchGroup* patchGroup, sint32 lineNumber, std::string_view errorMsg); - void logStageError(); + void showStageErrorMessageBox(); bool hasError() const { return m_anyErrorTriggered; }; diff --git a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp index a4dc5565..8338d93c 100644 --- a/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp +++ b/src/Cafe/HW/Latte/Core/LatteShaderCache.cpp @@ -357,8 +357,6 @@ void LatteShaderCache_Load() RendererShaderGL::ShaderCacheLoading_begin(cacheTitleId); // get cache file name const auto pathGeneric = ActiveSettings::GetCachePath("shaderCache/transferable/{:016x}_shaders.bin", cacheTitleId); - const auto pathGenericPre1_25_0 = ActiveSettings::GetCachePath("shaderCache/transferable/{:016x}.bin", cacheTitleId); // before 1.25.0 - const auto pathGenericPre1_16_0 = ActiveSettings::GetCachePath("shaderCache/transferable/{:08x}.bin", CafeSystem::GetRPXHashBase()); // before 1.16.0 // calculate extraVersion for transferable and precompiled shader cache uint32 transferableExtraVersion = SHADER_CACHE_GENERIC_EXTRA_VERSION; diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index 928990f0..612c2eaf 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -307,7 +307,7 @@ void VulkanRenderer::GetDeviceFeatures() cemuLog_log(LogType::Force, "VK_EXT_pipeline_creation_cache_control not supported. Cannot use asynchronous shader and pipeline compilation"); // if async shader compilation is enabled show warning message if (GetConfig().async_compile) - LatteOverlay_pushNotification("Async shader compile is enabled but not supported by the graphics driver\nCemu will use synchronous compilation which can cause additional stutter", 10000); + LatteOverlay_pushNotification(_tr("Async shader compile is enabled but not supported by the graphics driver\nCemu will use synchronous compilation which can cause additional stutter"), 10000); } if (!m_featureControl.deviceExtensions.custom_border_color_without_format) { diff --git a/src/Cafe/HW/MMU/MMU.cpp b/src/Cafe/HW/MMU/MMU.cpp index 14fced12..99c3185d 100644 --- a/src/Cafe/HW/MMU/MMU.cpp +++ b/src/Cafe/HW/MMU/MMU.cpp @@ -1,6 +1,7 @@ #include "Cafe/HW/MMU/MMU.h" #include "Cafe/GraphicPack/GraphicPack2.h" #include "Cemu/Logging/CemuLogging.h" +#include "WindowSystem.h" #include "util/MemMapper/MemMapper.h" #include "config/ActiveSettings.h" @@ -90,7 +91,8 @@ void MMURange::mapMem() cemu_assert_debug(!m_isMapped); if (MemMapper::AllocateMemory(memory_base + baseAddress, size, MemMapper::PAGE_PERMISSION::P_RW, true) == nullptr) { - cemuLog_log(LogType::Force, "Unable to allocate {} memory", name); + std::string errorMsg = fmt::format(fmt::runtime(_tr("Unable to allocate {} memory")), name); + WindowSystem::showErrorDialog(errorMsg, _tr("Error")); #if BOOST_OS_WINDOWS ExitProcess(-1); #else @@ -130,8 +132,9 @@ void memory_init() memory_base = (uint8*)MemMapper::ReserveMemory(nullptr, (size_t)0x100000000, MemMapper::PAGE_PERMISSION::P_RW); if( !memory_base ) { + debug_printf("memory_init(): Unable to reserve 4GB of memory\n"); debugBreakpoint(); - cemuLog_log(LogType::Force, "Unable to reserve 4GB of memory"); + WindowSystem::showErrorDialog(_tr("Unable to reserve 4GB of memory"), _tr("Error")); exit(-1); } for (auto& itr : g_mmuRanges) diff --git a/src/Cemu/Tools/DownloadManager/DownloadManager.cpp b/src/Cemu/Tools/DownloadManager/DownloadManager.cpp index 171e7fe3..0105b2d2 100644 --- a/src/Cemu/Tools/DownloadManager/DownloadManager.cpp +++ b/src/Cemu/Tools/DownloadManager/DownloadManager.cpp @@ -331,7 +331,9 @@ bool DownloadManager::syncAccountTickets() for (auto& tiv : resultTicketIds.tivs) { index++; - setStatus(DownloadManagerStatuses::DownloadingAccountTicket{.index = index, .count = count}); + std::string msg = _tr("Downloading account ticket"); + msg.append(fmt::format(" {0}/{1}", index, count)); + setStatusMessage(msg, DLMGR_STATUS_CODE::CONNECTING); // skip if already cached ETicketInfo* cachedTicket = findTicketByTicketId(tiv.ticketId); if (cachedTicket) @@ -382,7 +384,7 @@ bool DownloadManager::syncAccountTickets() bool DownloadManager::syncSystemTitleTickets() { - setStatus(DownloadManagerStatuses::DownloadingSystemTickets{}); + setStatusMessage(_tr("Downloading system tickets..."), DLMGR_STATUS_CODE::CONNECTING); NAPI::AuthInfo authInfo = GetAuthInfo(true); auto querySystemTitleTicket = [&](uint64 titleId) -> void { @@ -432,7 +434,7 @@ bool DownloadManager::syncSystemTitleTickets() // build list of updates for which either an installed game exists or the base title ticket is cached bool DownloadManager::syncUpdateTickets() { - setStatus(DownloadManagerStatuses::RetrievingUpdateInformation{}); + setStatusMessage(_tr("Retrieving update information..."), DLMGR_STATUS_CODE::CONNECTING); // download update version list downloadTitleVersionList(); if (!m_hasTitleVersionList) @@ -454,7 +456,10 @@ bool DownloadManager::syncUpdateTickets() if (titleIdParser.GetType() != TitleIdParser::TITLE_TYPE::BASE_TITLE_UPDATE) continue; - setStatus(DownloadManagerStatuses::DownloadingTicket{.updateIndex = updateIndex, .numUpdates = numUpdates}); + std::string msg = _tr("Downloading ticket"); + msg.append(fmt::format(" {0}/{1}", updateIndex, numUpdates)); + updateIndex++; + setStatusMessage(msg, DLMGR_STATUS_CODE::CONNECTING); if (!itr.isUpdateAvailable) continue; @@ -503,10 +508,12 @@ bool DownloadManager::syncTicketCache() for (auto& ticketInfo : m_ticketCache) { index++; - setStatus(DownloadManagerStatuses::DownloadingMetaData{.index = index, .count = count}); + std::string msg = _tr("Downloading meta data"); + msg.append(fmt::format(" {0}/{1}", index, count)); + setStatusMessage(msg, DLMGR_STATUS_CODE::CONNECTING); prepareIDBE(ticketInfo.titleId); } - setStatus(DownloadManagerStatuses::Connected{}); + setStatusMessage(_tr("Connected. Right click entries in the list to start downloading"), DLMGR_STATUS_CODE::CONNECTED); return true; } @@ -592,7 +599,7 @@ void DownloadManager::_handle_connect() // reset login state m_iasToken.serviceAccountId.clear(); m_iasToken.deviceToken.clear(); - setStatus(DownloadManagerStatuses::LoggingIn{}); + setStatusMessage(_tr("Logging in..."), DLMGR_STATUS_CODE::CONNECTING); // retrieve ECS AccountId + DeviceToken from cache if (s_nupFileCache) { @@ -615,7 +622,7 @@ void DownloadManager::_handle_connect() cemuLog_log(LogType::Force, "Failed to request IAS token"); cemu_assert_debug(false); m_connectState.store(CONNECT_STATE::FAILED); - setStatus(DownloadManagerStatuses::LoginFailed{}); + setStatusMessage(_tr("Login failed. Outdated or incomplete online files?"), DLMGR_STATUS_CODE::FAILED); return; } } @@ -623,16 +630,16 @@ void DownloadManager::_handle_connect() if (!_connect_queryAccountStatusAndServiceURLs()) { m_connectState.store(CONNECT_STATE::FAILED); - setStatus(DownloadManagerStatuses::FailedToQueryAccountStatus{}); + setStatusMessage(_tr("Failed to query account status"), DLMGR_STATUS_CODE::FAILED); return; } // load ticket cache and sync - setStatus(DownloadManagerStatuses::UpdatingTicketCache{}); + setStatusMessage(_tr("Updating ticket cache"), DLMGR_STATUS_CODE::CONNECTING); loadTicketCache(); if (!syncTicketCache()) { m_connectState.store(CONNECT_STATE::FAILED); - setStatus(DownloadManagerStatuses::FailedToRequestTickets{}); + setStatusMessage(_tr("Failed to request tickets"), DLMGR_STATUS_CODE::FAILED); return; } searchForIncompleteDownloads(); @@ -914,13 +921,13 @@ void DownloadManager::checkPackagesState() } } -void DownloadManager::setPackageError(Package* package, PackageErrorCode errorCode) +void DownloadManager::setPackageError(Package* package, std::string errorMsg) { package->state.isActive = false; if (package->state.hasError) return; // dont overwrite already set error message package->state.hasError = true; - package->state.errorCode = errorCode; + package->state.errorMsg = std::move(errorMsg); reportPackageStatus(package); } @@ -959,7 +966,7 @@ void DownloadManager::reportPackageStatus(Package* package) DlMgrTitleReport reportInfo(status, package->titleId, package->version, getNameFromCachedIDBE(package->titleId), package->state.progress, package->state.progressMax, package->state.isPaused); if (package->state.hasError) - reportInfo.errorCode = package->state.errorCode; + reportInfo.errorMsg = package->state.errorMsg; m_mutex.unlock(); m_cbAddDownloadableTitle(reportInfo); @@ -997,7 +1004,7 @@ void DownloadManager::asyncPackageDownloadTMD(Package* package) std::unique_lock _l(m_mutex); if (!tmdResult.isValid) { - setPackageError(package, PackageErrorCode::TMD_DOWNLOAD_FAILED); + setPackageError(package, _tr("TMD download failed")); package->state.isDownloadingTMD = false; return; } @@ -1006,7 +1013,7 @@ void DownloadManager::asyncPackageDownloadTMD(Package* package) NCrypto::TMDParser tmdParser; if (!tmdParser.parse(tmdResult.tmdData.data(), tmdResult.tmdData.size())) { - setPackageError(package, PackageErrorCode::INVALID_TMD); + setPackageError(package, _tr("Invalid TMD")); package->state.isDownloadingTMD = false; return; } @@ -1115,7 +1122,7 @@ void DownloadManager::asyncPackageDownloadContentFile(Package* package, uint16 i size_t bytesWritten = callbackInfo->receiveBuffer.size(); if (callbackInfo->fileOutput->writeData(callbackInfo->receiveBuffer.data(), callbackInfo->receiveBuffer.size()) != (uint32)callbackInfo->receiveBuffer.size()) { - callbackInfo->downloadMgr->setPackageError(callbackInfo->package, PackageErrorCode::DISK_FULL_FAILED_TO_WRITE_FILE); + callbackInfo->downloadMgr->setPackageError(callbackInfo->package, _tr("Cannot write file. Disk full?")); return false; } callbackInfo->receiveBuffer.clear(); @@ -1136,12 +1143,12 @@ void DownloadManager::asyncPackageDownloadContentFile(Package* package, uint16 i callbackInfoData.fileOutput = FileStream::createFile2(packageDownloadPath / fmt::format("{:08x}.app", contentId)); if (!callbackInfoData.fileOutput) { - setPackageError(package, PackageErrorCode::CANNOT_CREATE_FILE); + setPackageError(package, _tr("Cannot create file")); return; } if (!NAPI::CCS_GetContentFile(GetDownloadMgrNetworkService(), titleId, contentId, CallbackInfo::writeCallback, &callbackInfoData)) { - setPackageError(package, PackageErrorCode::DOWNLOAD_FAILED); + setPackageError(package, _tr("Download failed")); delete callbackInfoData.fileOutput; return; } @@ -1184,7 +1191,7 @@ void DownloadManager::asyncPackageVerifyFile(Package* package, uint16 index, boo _l.lock(); contentFileItr->second.finishProcessing(newStateOnError); if (!isCheckState) - setPackageError(package, PackageErrorCode::MISSING_FILE_DURING_VERIFICATION); + setPackageError(package, "Missing file during verification"); _l.unlock(); updatePackage(package); return; @@ -1203,7 +1210,7 @@ void DownloadManager::asyncPackageVerifyFile(Package* package, uint16 index, boo _l.lock(); contentFileItr->second.finishProcessing(newStateOnError); if (!isCheckState) - setPackageError(package, PackageErrorCode::VERIFICATION_FAILED); + setPackageError(package, "Verification failed"); _l.unlock(); updatePackage(package); return; @@ -1226,7 +1233,7 @@ bool DownloadManager::asyncPackageInstallRecursiveExtractFiles(Package* package, if (!fstVolume->OpenDirectoryIterator(sourcePath, dirItr)) { std::unique_lock _l(m_mutex); - setPackageError(package, PackageErrorCode::INTERNAL_ERROR); + setPackageError(package, "Internal error"); return false; } if (fstVolume->HasLinkFlag(dirItr.GetDirHandle())) @@ -1272,7 +1279,7 @@ bool DownloadManager::asyncPackageInstallRecursiveExtractFiles(Package* package, FileStream* fileOut = FileStream::createFile2(nodeDestinationPath); if (!fileOut) { - setPackageError(package, PackageErrorCode::FAILED_TO_CREATE_FILE); + setPackageError(package, "Failed to create file"); return false; } uint32 fileSize = fstVolume->GetFileSize(itr); @@ -1282,12 +1289,12 @@ bool DownloadManager::asyncPackageInstallRecursiveExtractFiles(Package* package, uint32 numBytesToTransfer = std::min(fileSize - currentPos, (uint32)buffer.size()); if (fstVolume->ReadFile(itr, currentPos, numBytesToTransfer, buffer.data()) != numBytesToTransfer) { - setPackageError(package, PackageErrorCode::FAILED_TO_EXTRACT_DATA); + setPackageError(package, "Failed to extract data"); return false; } if (fileOut->writeData(buffer.data(), numBytesToTransfer) != numBytesToTransfer) { - setPackageError(package, PackageErrorCode::DISK_FULL_FAILED_TO_WRITE_FILE); + setPackageError(package, "Failed to write to file. Disk full?"); return false; } currentPos += numBytesToTransfer; @@ -1317,7 +1324,7 @@ void DownloadManager::asyncPackageInstall(Package* package) if (!fileStream || fileStream->writeData(package->state.tmdData.data(), package->state.tmdData.size()) != package->state.tmdData.size()) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_WRITE_TITLE_TMD); + setPackageError(package, "Failed to write title.tmd"); package->state.isInstalling = false; return; } @@ -1327,7 +1334,7 @@ void DownloadManager::asyncPackageInstall(Package* package) if (!fileStream || fileStream->writeData(package->eTicketData.data(), package->eTicketData.size()) != package->eTicketData.size()) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_WRITE_TITLE_TIK); + setPackageError(package, "Failed to write title.tik"); package->state.isInstalling = false; return; } @@ -1343,7 +1350,7 @@ void DownloadManager::asyncPackageInstall(Package* package) if (!fileStream || fileStream->writeData(package->eTicketData.data(), package->eTicketData.size()) != package->eTicketData.size()) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_INSTALL_TITLE_TIK); + setPackageError(package, "Failed to install title.tik"); package->state.isInstalling = false; return; } @@ -1354,7 +1361,7 @@ void DownloadManager::asyncPackageInstall(Package* package) if (!fst) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_EXTRACT_CONTENT); + setPackageError(package, "Failed to extract content"); package->state.isInstalling = false; return; } @@ -1365,21 +1372,21 @@ void DownloadManager::asyncPackageInstall(Package* package) if (!asyncPackageInstallRecursiveExtractFiles(package, fst, "code/", installPath / "code")) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_EXTRACT_CODE_FOLDER); + setPackageError(package, "Failed to extract code folder"); package->state.isInstalling = false; return; } if (!asyncPackageInstallRecursiveExtractFiles(package, fst, "content/", installPath / "content")) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_EXTRACT_CONTENT_FOLDER); + setPackageError(package, "Failed to extract content folder"); package->state.isInstalling = false; return; } if (!asyncPackageInstallRecursiveExtractFiles(package, fst, "meta/", installPath / "meta")) { _l.lock(); - setPackageError(package, PackageErrorCode::FAILED_TO_EXTRACT_META_FOLDER); + setPackageError(package, "Failed to extract meta folder"); package->state.isInstalling = false; return; } diff --git a/src/Cemu/Tools/DownloadManager/DownloadManager.h b/src/Cemu/Tools/DownloadManager/DownloadManager.h index 4fe6e978..8f693a3e 100644 --- a/src/Cemu/Tools/DownloadManager/DownloadManager.h +++ b/src/Cemu/Tools/DownloadManager/DownloadManager.h @@ -5,8 +5,6 @@ #include "util/helpers/ConcurrentQueue.h" #include "config/NetworkSettings.h" -#include - // forward declarations namespace NAPI { @@ -19,27 +17,6 @@ namespace NCrypto class TMDParser; } -enum class PackageErrorCode -{ - TMD_DOWNLOAD_FAILED, - INVALID_TMD, - CANNOT_CREATE_FILE, - DOWNLOAD_FAILED, - MISSING_FILE_DURING_VERIFICATION, - VERIFICATION_FAILED, - INTERNAL_ERROR, - FAILED_TO_CREATE_FILE, - FAILED_TO_EXTRACT_DATA, - DISK_FULL_FAILED_TO_WRITE_FILE, - FAILED_TO_WRITE_TITLE_TMD, - FAILED_TO_WRITE_TITLE_TIK, - FAILED_TO_INSTALL_TITLE_TIK, - FAILED_TO_EXTRACT_CONTENT, - FAILED_TO_EXTRACT_CODE_FOLDER, - FAILED_TO_EXTRACT_CONTENT_FOLDER, - FAILED_TO_EXTRACT_META_FOLDER, -}; - struct DlMgrTitleReport { enum class STATUS @@ -68,7 +45,7 @@ struct DlMgrTitleReport uint32 progress; uint32 progressMax; bool isPaused; - PackageErrorCode errorCode; + std::string errorMsg; }; enum class DLMGR_STATUS_CODE @@ -79,82 +56,6 @@ enum class DLMGR_STATUS_CODE CONNECTED }; -namespace DownloadManagerStatuses -{ - struct Uninitialized - { - }; - - struct DownloadingAccountTicket - { - size_t index; - size_t count; - }; - - struct DownloadingSystemTickets - { - }; - - struct RetrievingUpdateInformation - { - }; - - struct DownloadingTicket - { - size_t updateIndex; - size_t numUpdates; - }; - - struct DownloadingMetaData - { - size_t index; - size_t count; - }; - - struct LoggingIn - { - }; - - struct UpdatingTicketCache - { - }; - - struct Failed - { - }; - - // Outdated or incomplete online files? - struct LoginFailed : Failed - { - }; - - struct FailedToQueryAccountStatus : Failed - { - }; - - struct FailedToRequestTickets : Failed - { - }; - - struct Connected - { - }; -}; // namespace DownloadManagerStatuses - -using DownloadManagerStatus = std::variant< - DownloadManagerStatuses::Uninitialized, - DownloadManagerStatuses::DownloadingAccountTicket, - DownloadManagerStatuses::DownloadingSystemTickets, - DownloadManagerStatuses::RetrievingUpdateInformation, - DownloadManagerStatuses::DownloadingTicket, - DownloadManagerStatuses::DownloadingMetaData, - DownloadManagerStatuses::LoggingIn, - DownloadManagerStatuses::UpdatingTicketCache, - DownloadManagerStatuses::LoginFailed, - DownloadManagerStatuses::FailedToQueryAccountStatus, - DownloadManagerStatuses::FailedToRequestTickets, - DownloadManagerStatuses::Connected>; - class DownloadManager { public: @@ -451,7 +352,7 @@ private: bool isInstalling{}; // error state bool hasError{}; - PackageErrorCode errorCode; + std::string errorMsg; }state; }; @@ -469,7 +370,7 @@ private: void updatePackage(Package* package); void checkPackagesState(); - void setPackageError(Package* package, PackageErrorCode errorCode); + void setPackageError(Package* package, std::string errorMsg); void reportPackageStatus(Package* package); void reportPackageProgress(Package* package, uint32 newProgress); @@ -495,7 +396,7 @@ public: // register/unregister callbacks // setting valid callbacks will also trigger transfer of the entire title/package state and the current status message void registerCallbacks( - void(*cbUpdateConnectStatus)(DownloadManagerStatus), + void(*cbUpdateConnectStatus)(std::string statusText, DLMGR_STATUS_CODE statusCode), void(*cbAddDownloadableTitle)(const DlMgrTitleReport& titleInfo), void(*cbRemoveDownloadableTitle)(uint64 titleId, uint16 version) ) @@ -508,22 +409,23 @@ public: if (m_cbUpdateConnectStatus || m_cbAddDownloadableTitle) { std::unique_lock _l(m_mutex); - setStatus(m_status); + setStatusMessage(m_statusMessage, m_statusCode); reportAvailableTitles(); for (auto& p : m_packageList) reportPackageStatus(p); } } - void setStatus(DownloadManagerStatus status) + void setStatusMessage(std::string_view msg, DLMGR_STATUS_CODE statusCode) { - m_status = status; + m_statusMessage = msg; + m_statusCode = statusCode; if (m_cbUpdateConnectStatus) - m_cbUpdateConnectStatus(status); + m_cbUpdateConnectStatus(m_statusMessage, statusCode); } std::string m_statusMessage{}; - DownloadManagerStatus m_status = DownloadManagerStatuses::Uninitialized{}; + DLMGR_STATUS_CODE m_statusCode{ DLMGR_STATUS_CODE::UNINITIALIZED }; bool hasActiveDownloads() { @@ -543,12 +445,12 @@ public: { std::unique_lock _l(m_mutex); m_packageList.clear(); - m_status = DownloadManagerStatuses::Uninitialized{}; + m_statusCode = DLMGR_STATUS_CODE::UNINITIALIZED; m_statusMessage.clear(); } private: - void(*m_cbUpdateConnectStatus)(DownloadManagerStatus status) { nullptr }; + void(*m_cbUpdateConnectStatus)(std::string statusText, DLMGR_STATUS_CODE statusCode) { nullptr }; void(*m_cbAddDownloadableTitle)(const DlMgrTitleReport& titleInfo); void(*m_cbRemoveDownloadableTitle)(uint64 titleId, uint16 version); void* m_userData{}; diff --git a/src/Common/precompiled.h b/src/Common/precompiled.h index 8b724c6c..d4db9d84 100644 --- a/src/Common/precompiled.h +++ b/src/Common/precompiled.h @@ -119,6 +119,27 @@ using uint8le = uint8_t; #include "Cemu/Logging/CemuDebugLogging.h" #include "Cemu/Logging/CemuLogging.h" +// localization +namespace +{ + std::function g_translate; +} + +inline void SetTranslationCallback(std::function translate) +{ + g_translate = translate; +} + +#define TR_NOOP(str) str + +inline std::string _tr(std::string_view msgId) +{ + if (g_translate) + return g_translate(msgId); + + return std::string{msgId}; +} + // manual endian-swapping #if _MSC_VER diff --git a/src/config/CemuConfig.h b/src/config/CemuConfig.h index fdd24aea..7fc8e48c 100644 --- a/src/config/CemuConfig.h +++ b/src/config/CemuConfig.h @@ -258,15 +258,15 @@ struct fmt::formatter : formatter { string_view name; switch (v) { - case CafeConsoleRegion::JPN: name = "Japan"; break; - case CafeConsoleRegion::USA: name = "USA"; break; - case CafeConsoleRegion::EUR: name = "Europe"; break; - case CafeConsoleRegion::AUS_DEPR: name = "Australia"; break; - case CafeConsoleRegion::CHN: name = "China"; break; - case CafeConsoleRegion::KOR: name = "Korea"; break; - case CafeConsoleRegion::TWN: name = "Taiwan"; break; - case CafeConsoleRegion::Auto: name = "Auto"; break; - default: name = "many"; break; + case CafeConsoleRegion::JPN: name = TR_NOOP("Japan"); break; + case CafeConsoleRegion::USA: name = TR_NOOP("USA"); break; + case CafeConsoleRegion::EUR: name = TR_NOOP("Europe"); break; + case CafeConsoleRegion::AUS_DEPR: name = TR_NOOP("Australia"); break; + case CafeConsoleRegion::CHN: name = TR_NOOP("China"); break; + case CafeConsoleRegion::KOR: name = TR_NOOP("Korea"); break; + case CafeConsoleRegion::TWN: name = TR_NOOP("Taiwan"); break; + case CafeConsoleRegion::Auto: name = TR_NOOP("Auto"); break; + default: name = TR_NOOP("many"); break; } return formatter::format(name, ctx); diff --git a/src/config/LaunchSettings.cpp b/src/config/LaunchSettings.cpp index 238944bc..4ac12c53 100644 --- a/src/config/LaunchSettings.cpp +++ b/src/config/LaunchSettings.cpp @@ -222,7 +222,10 @@ bool LaunchSettings::HandleCommandline(const std::vector& args) } catch (const std::exception& ex) { - cemuLog_log(LogType::Force, "Error while trying to parse command line parameter: {}", ex.what()); + std::string errorMsg; + errorMsg.append("Error while trying to parse command line parameter:\n"); + errorMsg.append(ex.what()); + std::cout << errorMsg << std::endl; return false; } diff --git a/src/gui/interface/WindowSystem.h b/src/gui/interface/WindowSystem.h index fb05fe12..f3122cd6 100644 --- a/src/gui/interface/WindowSystem.h +++ b/src/gui/interface/WindowSystem.h @@ -82,6 +82,18 @@ namespace WindowSystem std::unordered_map m_keydown; }; + enum class ErrorCategory + { + KEYS_TXT_CREATION = 0, + GRAPHIC_PACKS = 1, + }; + + void showErrorDialog(std::string_view message, std::string_view title, std::optional errorCategory = {}); + inline void showErrorDialog(std::string_view message, std::optional errorCategory = {}) + { + showErrorDialog(message, "", errorCategory); + } + void create(); WindowInfo& getWindowInfo(); diff --git a/src/gui/wxgui/CemuApp.cpp b/src/gui/wxgui/CemuApp.cpp index 5ae2b353..0fd26cb0 100644 --- a/src/gui/wxgui/CemuApp.cpp +++ b/src/gui/wxgui/CemuApp.cpp @@ -247,6 +247,11 @@ void CemuApp::InitializeExistingMLCOrFail(fs::path mlc) } } +std::string TranslationCallback(std::string_view msgId) +{ + return wxGetTranslation(to_wxString(msgId)).utf8_string(); +} + bool CemuApp::OnInit() { #if __WXGTK__ @@ -273,6 +278,8 @@ bool CemuApp::OnInit() LocalizeUI(static_cast(wxLocale::GetSystemLanguage())); } + SetTranslationCallback(TranslationCallback); + for (auto&& path : failedWriteAccess) { wxMessageBox(formatWxString(_("Cemu can't write to {}!"), wxString::FromUTF8(_pathToUtf8(path))), diff --git a/src/gui/wxgui/TitleManager.cpp b/src/gui/wxgui/TitleManager.cpp index c039aa66..e94bb5bf 100644 --- a/src/gui/wxgui/TitleManager.cpp +++ b/src/gui/wxgui/TitleManager.cpp @@ -11,8 +11,6 @@ #include "wxgui/GameUpdateWindow.h" #include "wxgui/dialogs/SaveImport/SaveTransfer.h" -#include -#include #include #include #include @@ -819,50 +817,11 @@ void TitleManager::SetConnected(bool state) m_download_list->Enable(state); } -void TitleManager::Callback_ConnectStatusUpdate(DownloadManagerStatus status) +void TitleManager::Callback_ConnectStatusUpdate(std::string statusText, DLMGR_STATUS_CODE statusCode) { TitleManager* titleManager = static_cast(DownloadManager::GetInstance()->getUserData()); - auto downloadStatusText = std::visit([](auto&& status) -> std::optional { - using T = std::decay_t; - if constexpr (std::is_same_v) - return std::nullopt; - else if constexpr (std::is_same_v) - return _("Downloading account ticket") + fmt::format(" {0}/{1}", status.index, status.count); - else if constexpr (std::is_same_v) - return _("Downloading system tickets..."); - else if constexpr (std::is_same_v) - return _("Retrieving update information..."); - else if constexpr (std::is_same_v) - return _("Downloading ticket") + fmt::format(" {0}/{1}", status.updateIndex, status.numUpdates); - else if constexpr (std::is_same_v) - return _("Downloading meta data") + fmt::format(" {0}/{1}", status.index, status.count); - else if constexpr (std::is_same_v) - return _("Logging in..."); - else if constexpr (std::is_same_v) - return _("Updating ticket cache"); - else if constexpr (std::is_same_v) - return _("Login failed. Outdated or incomplete online files?"); - else if constexpr (std::is_same_v) - return _("Failed to query account status"); - else if constexpr (std::is_same_v) - return _("Failed to request tickets"); - else if constexpr (std::is_same_v) - return _("Connected. Right click entries in the list to start downloading"); - - cemu_assert_unimplemented(); - return std::nullopt; }, status); - - if (!downloadStatusText.has_value()) - { - return; - } - - titleManager->SetDownloadStatusText(downloadStatusText.value()); - bool isFailedStatus = std::visit([](auto&& status) -> bool { - constexpr bool isFailedStatus = std::is_base_of_v>; - return isFailedStatus; }, status); - - if (isFailedStatus) + titleManager->SetDownloadStatusText(wxString::FromUTF8(statusText)); + if (statusCode == DLMGR_STATUS_CODE::FAILED) { auto* evt = new wxCommandEvent(wxEVT_DL_DISCONNECT_COMPLETE); wxQueueEvent(titleManager, evt); // this will set SetConnected() to false @@ -870,29 +829,6 @@ void TitleManager::Callback_ConnectStatusUpdate(DownloadManagerStatus status) } } -wxString getPackageErrorMessage(PackageErrorCode code) { - switch (code) { - case PackageErrorCode::TMD_DOWNLOAD_FAILED: return _("TMD download failed"); - case PackageErrorCode::INVALID_TMD: return _("Invalid TMD"); - case PackageErrorCode::CANNOT_CREATE_FILE: return _("Cannot create file"); - case PackageErrorCode::DOWNLOAD_FAILED: return _("Download failed"); - case PackageErrorCode::MISSING_FILE_DURING_VERIFICATION: return _("Missing file during verification"); - case PackageErrorCode::VERIFICATION_FAILED: return _("Verification failed"); - case PackageErrorCode::INTERNAL_ERROR: return _("Internal error"); - case PackageErrorCode::FAILED_TO_CREATE_FILE: return _("Failed to create file"); - case PackageErrorCode::FAILED_TO_EXTRACT_DATA: return _("Failed to extract data"); - case PackageErrorCode::DISK_FULL_FAILED_TO_WRITE_FILE: return _("Failed to write to file. Disk full?"); - case PackageErrorCode::FAILED_TO_WRITE_TITLE_TMD: return _("Failed to write title.tmd"); - case PackageErrorCode::FAILED_TO_WRITE_TITLE_TIK: return _("Failed to write title.tik"); - case PackageErrorCode::FAILED_TO_INSTALL_TITLE_TIK: return _("Failed to install title.tik"); - case PackageErrorCode::FAILED_TO_EXTRACT_CONTENT: return _("Failed to extract content"); - case PackageErrorCode::FAILED_TO_EXTRACT_CODE_FOLDER: return _("Failed to extract code folder"); - case PackageErrorCode::FAILED_TO_EXTRACT_CONTENT_FOLDER: return _("Failed to extract content folder"); - case PackageErrorCode::FAILED_TO_EXTRACT_META_FOLDER: return _("Failed to extract meta folder"); - default: return _("Unknown error"); - } -} - void TitleManager::Callback_AddDownloadableTitle(const DlMgrTitleReport& titleInfo) { TitleManager* titleManager = static_cast(DownloadManager::GetInstance()->getUserData()); @@ -949,7 +885,7 @@ void TitleManager::Callback_AddDownloadableTitle(const DlMgrTitleReport& titleIn break; case DlMgrTitleReport::STATUS::HAS_ERROR: titleEntry.status = wxDownloadManagerList::TitleDownloadStatus::Error; - titleEntry.errorMsg = getPackageErrorMessage(titleInfo.errorCode); + titleEntry.errorMsg = titleInfo.errorMsg; break; default: titleEntry.status = wxDownloadManagerList::TitleDownloadStatus::None; diff --git a/src/gui/wxgui/TitleManager.h b/src/gui/wxgui/TitleManager.h index 2ff21305..ae284040 100644 --- a/src/gui/wxgui/TitleManager.h +++ b/src/gui/wxgui/TitleManager.h @@ -30,6 +30,8 @@ enum class TitleManagerPage DownloadManager = 1 }; +enum class DLMGR_STATUS_CODE; + class TitleManager : public wxFrame { public: @@ -89,7 +91,7 @@ private: void SetConnected(bool state); - static void Callback_ConnectStatusUpdate(DownloadManagerStatus status); + static void Callback_ConnectStatusUpdate(std::string statusText, DLMGR_STATUS_CODE statusCode); static void Callback_AddDownloadableTitle(const struct DlMgrTitleReport& titleInfo); static void Callback_RemoveDownloadableTitle(uint64 titleId, uint16 version); diff --git a/src/gui/wxgui/input/panels/ClassicControllerInputPanel.cpp b/src/gui/wxgui/input/panels/ClassicControllerInputPanel.cpp index 56544bb9..ced1cede 100644 --- a/src/gui/wxgui/input/panels/ClassicControllerInputPanel.cpp +++ b/src/gui/wxgui/input/panels/ClassicControllerInputPanel.cpp @@ -101,69 +101,9 @@ ClassicControllerInputPanel::ClassicControllerInputPanel(wxWindow* parent) Layout(); } -wxString get_classic_controller_button_name(ClassicController::ButtonId id) -{ - switch (id) - { - case ClassicController::kButtonId_A: - return "A"; - case ClassicController::kButtonId_B: - return "B"; - case ClassicController::kButtonId_X: - return "X"; - case ClassicController::kButtonId_Y: - return "Y"; - case ClassicController::kButtonId_L: - return "L"; - case ClassicController::kButtonId_R: - return "R"; - case ClassicController::kButtonId_ZL: - return "ZL"; - case ClassicController::kButtonId_ZR: - return "ZR"; - - case ClassicController::kButtonId_Plus: - return "+"; - case ClassicController::kButtonId_Minus: - return "-"; - case ClassicController::kButtonId_Home: - return _("home"); - - case ClassicController::kButtonId_Up: - return _("up"); - case ClassicController::kButtonId_Down: - return _("down"); - case ClassicController::kButtonId_Left: - return _("left"); - case ClassicController::kButtonId_Right: - return _("right"); - - case ClassicController::kButtonId_StickL_Up: - return _("up"); - case ClassicController::kButtonId_StickL_Down: - return _("down"); - case ClassicController::kButtonId_StickL_Left: - return _("left"); - case ClassicController::kButtonId_StickL_Right: - return _("right"); - - case ClassicController::kButtonId_StickR_Up: - return _("up"); - case ClassicController::kButtonId_StickR_Down: - return _("down"); - case ClassicController::kButtonId_StickR_Left: - return _("left"); - case ClassicController::kButtonId_StickR_Right: - return _("right"); - - default: - return ""; - } -} - void ClassicControllerInputPanel::add_button_row(wxGridBagSizer *sizer, sint32 row, sint32 column, const ClassicController::ButtonId &button_id) { sizer->Add( - new wxStaticText(this, wxID_ANY, get_classic_controller_button_name(button_id)), + new wxStaticText(this, wxID_ANY, wxGetTranslation(to_wxString(ClassicController::get_button_name(button_id)))), wxGBPosition(row, column), wxDefaultSpan, wxALL | wxALIGN_CENTER_VERTICAL, 5); diff --git a/src/gui/wxgui/input/panels/ProControllerInputPanel.cpp b/src/gui/wxgui/input/panels/ProControllerInputPanel.cpp index cf902483..d8e50b03 100644 --- a/src/gui/wxgui/input/panels/ProControllerInputPanel.cpp +++ b/src/gui/wxgui/input/panels/ProControllerInputPanel.cpp @@ -99,70 +99,9 @@ ProControllerInputPanel::ProControllerInputPanel(wxWindow* parent) SetSizerAndFit(main_sizer); } -wxString get_pro_controller_button_name(ProController::ButtonId id) -{ - switch (id) - { - case ProController::kButtonId_A: - return "A"; - case ProController::kButtonId_B: - return "B"; - case ProController::kButtonId_X: - return "X"; - case ProController::kButtonId_Y: - return "Y"; - case ProController::kButtonId_L: - return "L"; - case ProController::kButtonId_R: - return "R"; - case ProController::kButtonId_ZL: - return "ZL"; - case ProController::kButtonId_ZR: - return "ZR"; - case ProController::kButtonId_Plus: - return "+"; - case ProController::kButtonId_Minus: - return "-"; - case ProController::kButtonId_Up: - return _("up"); - case ProController::kButtonId_Down: - return _("down"); - case ProController::kButtonId_Left: - return _("left"); - case ProController::kButtonId_Right: - return _("right"); - case ProController::kButtonId_StickL: - return _("click"); - case ProController::kButtonId_StickR: - return _("click"); - case ProController::kButtonId_StickL_Up: - return _("up"); - case ProController::kButtonId_StickL_Down: - return _("down"); - case ProController::kButtonId_StickL_Left: - return _("left"); - case ProController::kButtonId_StickL_Right: - return _("right"); - case ProController::kButtonId_StickR_Up: - return _("up"); - case ProController::kButtonId_StickR_Down: - return _("down"); - case ProController::kButtonId_StickR_Left: - return _("left"); - case ProController::kButtonId_StickR_Right: - return _("right"); - case ProController::kButtonId_Home: - return _("home"); - default: - cemu_assert_debug(false); - return ""; - } -} - -void ProControllerInputPanel::add_button_row(wxGridBagSizer* sizer, sint32 row, sint32 column, const ProController::ButtonId& button_id) -{ +void ProControllerInputPanel::add_button_row(wxGridBagSizer *sizer, sint32 row, sint32 column, const ProController::ButtonId &button_id) { sizer->Add( - new wxStaticText(this, wxID_ANY, get_pro_controller_button_name(button_id)), + new wxStaticText(this, wxID_ANY, wxGetTranslation(to_wxString(ProController::get_button_name(button_id)))), wxGBPosition(row, column), wxDefaultSpan, wxALL | wxALIGN_CENTER_VERTICAL, 5); diff --git a/src/gui/wxgui/input/panels/VPADInputPanel.cpp b/src/gui/wxgui/input/panels/VPADInputPanel.cpp index e6ca1c8b..f59aad10 100644 --- a/src/gui/wxgui/input/panels/VPADInputPanel.cpp +++ b/src/gui/wxgui/input/panels/VPADInputPanel.cpp @@ -156,68 +156,8 @@ VPADInputPanel::VPADInputPanel(wxWindow* parent) Layout(); } -wxString get_vpad_controllerbutton_name(VPADController::ButtonId id) -{ - switch (id) - { - case VPADController::kButtonId_A: - return "A"; - case VPADController::kButtonId_B: - return "B"; - case VPADController::kButtonId_X: - return "X"; - case VPADController::kButtonId_Y: - return "Y"; - case VPADController::kButtonId_L: - return "L"; - case VPADController::kButtonId_R: - return "R"; - case VPADController::kButtonId_ZL: - return "ZL"; - case VPADController::kButtonId_ZR: - return "ZR"; - case VPADController::kButtonId_Plus: - return "+"; - case VPADController::kButtonId_Minus: - return "-"; - case VPADController::kButtonId_Up: - return _("up"); - case VPADController::kButtonId_Down: - return _("down"); - case VPADController::kButtonId_Left: - return _("left"); - case VPADController::kButtonId_Right: - return _("right"); - case VPADController::kButtonId_StickL: - return _("click"); - case VPADController::kButtonId_StickR: - return _("click"); - case VPADController::kButtonId_StickL_Up: - return _("up"); - case VPADController::kButtonId_StickL_Down: - return _("down"); - case VPADController::kButtonId_StickL_Left: - return _("left"); - case VPADController::kButtonId_StickL_Right: - return _("right"); - case VPADController::kButtonId_StickR_Up: - return _("up"); - case VPADController::kButtonId_StickR_Down: - return _("down"); - case VPADController::kButtonId_StickR_Left: - return _("left"); - case VPADController::kButtonId_StickR_Right: - return _("right"); - case VPADController::kButtonId_Home: - return _("home"); - default: - cemu_assert_debug(false); - return ""; - } -} - void VPADInputPanel::add_button_row(wxGridBagSizer *sizer, sint32 row, sint32 column, const VPADController::ButtonId &button_id) { - add_button_row(sizer, row, column, button_id, get_vpad_controllerbutton_name(button_id)); + add_button_row(sizer, row, column, button_id, wxGetTranslation(to_wxString(VPADController::get_button_name(button_id)))); } void VPADInputPanel::add_button_row(wxGridBagSizer *sizer, sint32 row, sint32 column, diff --git a/src/gui/wxgui/input/panels/WiimoteInputPanel.cpp b/src/gui/wxgui/input/panels/WiimoteInputPanel.cpp index f33ca838..e40c601f 100644 --- a/src/gui/wxgui/input/panels/WiimoteInputPanel.cpp +++ b/src/gui/wxgui/input/panels/WiimoteInputPanel.cpp @@ -156,57 +156,9 @@ WiimoteInputPanel::WiimoteInputPanel(wxWindow* parent) Layout(); } -wxString get_wiimote_controller_button_name(WiimoteController::ButtonId id) -{ - switch (id) - { - case WiimoteController::kButtonId_A: - return "A"; - case WiimoteController::kButtonId_B: - return "B"; - case WiimoteController::kButtonId_1: - return "1"; - case WiimoteController::kButtonId_2: - return "2"; - - case WiimoteController::kButtonId_Home: - return _("home"); - case WiimoteController::kButtonId_Plus: - return "+"; - case WiimoteController::kButtonId_Minus: - return "-"; - - case WiimoteController::kButtonId_Up: - return _("up"); - case WiimoteController::kButtonId_Down: - return _("down"); - case WiimoteController::kButtonId_Left: - return _("left"); - case WiimoteController::kButtonId_Right: - return _("right"); - - case WiimoteController::kButtonId_Nunchuck_Z: - return "Z"; - case WiimoteController::kButtonId_Nunchuck_C: - return "C"; - - case WiimoteController::kButtonId_Nunchuck_Up: - return _("up"); - case WiimoteController::kButtonId_Nunchuck_Down: - return _("down"); - case WiimoteController::kButtonId_Nunchuck_Left: - return _("left"); - case WiimoteController::kButtonId_Nunchuck_Right: - return _("right"); - - default: - return ""; - } -} - void WiimoteInputPanel::add_button_row(sint32 row, sint32 column, const WiimoteController::ButtonId &button_id) { m_item_sizer->Add( - new wxStaticText(this, wxID_ANY, get_wiimote_controller_button_name(button_id)), + new wxStaticText(this, wxID_ANY, wxGetTranslation(to_wxString(WiimoteController::get_button_name(button_id)))), wxGBPosition(row, column), wxDefaultSpan, wxALL | wxALIGN_CENTER_VERTICAL, 5); diff --git a/src/gui/wxgui/wxWindowSystem.cpp b/src/gui/wxgui/wxWindowSystem.cpp index f87303e5..deff25c2 100644 --- a/src/gui/wxgui/wxWindowSystem.cpp +++ b/src/gui/wxgui/wxWindowSystem.cpp @@ -1,5 +1,7 @@ #include "interface/WindowSystem.h" +#include "helpers/wxHelpers.h" + #if BOOST_OS_LINUX #include #include @@ -53,6 +55,16 @@ void WindowSystem::create() #endif } +void WindowSystem::showErrorDialog(std::string_view message, std::string_view title, std::optional /*errorId*/) +{ + wxString caption; + if (title.empty()) + caption = wxASCII_STR(wxMessageBoxCaptionStr); + else + caption = to_wxString(title); + wxMessageBox(to_wxString(message), caption, wxOK | wxCENTRE | wxICON_ERROR); +} + WindowSystem::WindowInfo& WindowSystem::getWindowInfo() { return g_window_info; diff --git a/src/input/emulated/ClassicController.cpp b/src/input/emulated/ClassicController.cpp index e218cded..3386aefe 100644 --- a/src/input/emulated/ClassicController.cpp +++ b/src/input/emulated/ClassicController.cpp @@ -68,22 +68,22 @@ std::string_view ClassicController::get_button_name(ButtonId id) case kButtonId_Plus: return "+"; case kButtonId_Minus: return "-"; - case kButtonId_Home: return "home"; + case kButtonId_Home: return TR_NOOP("home"); - case kButtonId_Up: return "up"; - case kButtonId_Down: return "down"; - case kButtonId_Left: return "left"; - case kButtonId_Right: return "right"; + case kButtonId_Up: return TR_NOOP("up"); + case kButtonId_Down: return TR_NOOP("down"); + case kButtonId_Left: return TR_NOOP("left"); + case kButtonId_Right: return TR_NOOP("right"); - case kButtonId_StickL_Up: return "up"; - case kButtonId_StickL_Down: return "down"; - case kButtonId_StickL_Left: return "left"; - case kButtonId_StickL_Right: return "right"; + case kButtonId_StickL_Up: return TR_NOOP("up"); + case kButtonId_StickL_Down: return TR_NOOP("down"); + case kButtonId_StickL_Left: return TR_NOOP("left"); + case kButtonId_StickL_Right: return TR_NOOP("right"); - case kButtonId_StickR_Up: return "up"; - case kButtonId_StickR_Down: return "down"; - case kButtonId_StickR_Left: return "left"; - case kButtonId_StickR_Right: return "right"; + case kButtonId_StickR_Up: return TR_NOOP("up"); + case kButtonId_StickR_Down: return TR_NOOP("down"); + case kButtonId_StickR_Left: return TR_NOOP("left"); + case kButtonId_StickR_Right: return TR_NOOP("right"); default: return ""; diff --git a/src/input/emulated/ProController.cpp b/src/input/emulated/ProController.cpp index 521f88b2..8b8ab29b 100644 --- a/src/input/emulated/ProController.cpp +++ b/src/input/emulated/ProController.cpp @@ -73,21 +73,21 @@ std::string_view ProController::get_button_name(ButtonId id) case kButtonId_ZR: return "ZR"; case kButtonId_Plus: return "+"; case kButtonId_Minus: return "-"; - case kButtonId_Up: return "up"; - case kButtonId_Down: return "down"; - case kButtonId_Left: return "left"; - case kButtonId_Right: return "right"; - case kButtonId_StickL: return "click"; - case kButtonId_StickR: return "click"; - case kButtonId_StickL_Up: return "up"; - case kButtonId_StickL_Down: return "down"; - case kButtonId_StickL_Left: return "left"; - case kButtonId_StickL_Right: return "right"; - case kButtonId_StickR_Up: return "up"; - case kButtonId_StickR_Down: return "down"; - case kButtonId_StickR_Left: return "left"; - case kButtonId_StickR_Right: return "right"; - case kButtonId_Home: return "home"; + case kButtonId_Up: return TR_NOOP("up"); + case kButtonId_Down: return TR_NOOP("down"); + case kButtonId_Left: return TR_NOOP("left"); + case kButtonId_Right: return TR_NOOP("right"); + case kButtonId_StickL: return TR_NOOP("click"); + case kButtonId_StickR: return TR_NOOP("click"); + case kButtonId_StickL_Up: return TR_NOOP("up"); + case kButtonId_StickL_Down: return TR_NOOP("down"); + case kButtonId_StickL_Left: return TR_NOOP("left"); + case kButtonId_StickL_Right: return TR_NOOP("right"); + case kButtonId_StickR_Up: return TR_NOOP("up"); + case kButtonId_StickR_Down: return TR_NOOP("down"); + case kButtonId_StickR_Left: return TR_NOOP("left"); + case kButtonId_StickR_Right: return TR_NOOP("right"); + case kButtonId_Home: return TR_NOOP("home"); default: cemu_assert_debug(false); return ""; diff --git a/src/input/emulated/VPADController.cpp b/src/input/emulated/VPADController.cpp index 28288662..531e83f5 100644 --- a/src/input/emulated/VPADController.cpp +++ b/src/input/emulated/VPADController.cpp @@ -366,21 +366,21 @@ std::string_view VPADController::get_button_name(ButtonId id) case kButtonId_ZR: return "ZR"; case kButtonId_Plus: return "+"; case kButtonId_Minus: return "-"; - case kButtonId_Up: return "up"; - case kButtonId_Down: return "down"; - case kButtonId_Left: return "left"; - case kButtonId_Right: return "right"; - case kButtonId_StickL: return "click"; - case kButtonId_StickR: return "click"; - case kButtonId_StickL_Up: return "up"; - case kButtonId_StickL_Down: return "down"; - case kButtonId_StickL_Left: return "left"; - case kButtonId_StickL_Right: return "right"; - case kButtonId_StickR_Up: return "up"; - case kButtonId_StickR_Down: return "down"; - case kButtonId_StickR_Left: return "left"; - case kButtonId_StickR_Right: return "right"; - case kButtonId_Home: return "home"; + case kButtonId_Up: return TR_NOOP("up"); + case kButtonId_Down: return TR_NOOP("down"); + case kButtonId_Left: return TR_NOOP("left"); + case kButtonId_Right: return TR_NOOP("right"); + case kButtonId_StickL: return TR_NOOP("click"); + case kButtonId_StickR: return TR_NOOP("click"); + case kButtonId_StickL_Up: return TR_NOOP("up"); + case kButtonId_StickL_Down: return TR_NOOP("down"); + case kButtonId_StickL_Left: return TR_NOOP("left"); + case kButtonId_StickL_Right: return TR_NOOP("right"); + case kButtonId_StickR_Up: return TR_NOOP("up"); + case kButtonId_StickR_Down: return TR_NOOP("down"); + case kButtonId_StickR_Left: return TR_NOOP("left"); + case kButtonId_StickR_Right: return TR_NOOP("right"); + case kButtonId_Home: return TR_NOOP("home"); default: cemu_assert_debug(false); return ""; diff --git a/src/input/emulated/WiimoteController.cpp b/src/input/emulated/WiimoteController.cpp index 578a9527..46921f8b 100644 --- a/src/input/emulated/WiimoteController.cpp +++ b/src/input/emulated/WiimoteController.cpp @@ -158,22 +158,22 @@ std::string_view WiimoteController::get_button_name(ButtonId id) case kButtonId_1: return "1"; case kButtonId_2: return "2"; - case kButtonId_Home: return "home"; + case kButtonId_Home: return TR_NOOP("home"); case kButtonId_Plus: return "+"; case kButtonId_Minus: return "-"; - case kButtonId_Up: return "up"; - case kButtonId_Down: return "down"; - case kButtonId_Left: return "left"; - case kButtonId_Right: return "right"; + case kButtonId_Up: return TR_NOOP("up"); + case kButtonId_Down: return TR_NOOP("down"); + case kButtonId_Left: return TR_NOOP("left"); + case kButtonId_Right: return TR_NOOP("right"); case kButtonId_Nunchuck_Z: return "Z"; case kButtonId_Nunchuck_C: return "C"; - case kButtonId_Nunchuck_Up: return "up"; - case kButtonId_Nunchuck_Down: return "down"; - case kButtonId_Nunchuck_Left: return "left"; - case kButtonId_Nunchuck_Right: return "right"; + case kButtonId_Nunchuck_Up: return TR_NOOP("up"); + case kButtonId_Nunchuck_Down: return TR_NOOP("down"); + case kButtonId_Nunchuck_Left: return TR_NOOP("left"); + case kButtonId_Nunchuck_Right: return TR_NOOP("right"); default: return ""; diff --git a/src/util/helpers/helpers.cpp b/src/util/helpers/helpers.cpp index 2bc86ce7..d2636845 100644 --- a/src/util/helpers/helpers.cpp +++ b/src/util/helpers/helpers.cpp @@ -51,29 +51,6 @@ std::string_view& trim(std::string_view& str, const std::string& chars) #if BOOST_OS_WINDOWS -std::wstring GetSystemErrorMessageW() -{ - return GetSystemErrorMessageW(GetLastError()); -} - - -std::wstring GetSystemErrorMessageW(DWORD error_code) -{ - if(error_code == ERROR_SUCCESS) - return {}; - - LPWSTR lpMsgBuf = nullptr; - FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error_code, 0, (LPWSTR)&lpMsgBuf, 0, nullptr); - if (lpMsgBuf) - { - std::wstring str = fmt::format(L"{}: {}", L"Error", lpMsgBuf); - LocalFree(lpMsgBuf); - return str; - } - - return fmt::format(L"{}: {:#x}", L"Error code", error_code); -} - std::string GetSystemErrorMessage(DWORD error_code) { if(error_code == ERROR_SUCCESS) @@ -83,12 +60,12 @@ std::string GetSystemErrorMessage(DWORD error_code) FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, error_code, 0, (LPSTR)&lpMsgBuf, 0, nullptr); if (lpMsgBuf) { - std::string str = fmt::format("{}: {}", "Error", lpMsgBuf); + std::string str = fmt::format("{}: {}", _tr("Error") lpMsgBuf); // TRANSLATE LocalFree(lpMsgBuf); return str; } - return fmt::format("{}: {:#x}", "Error code", error_code); + return fmt::format("{}: {:#x}", _tr("Error code"), error_code); } std::string GetSystemErrorMessage() diff --git a/src/util/helpers/helpers.h b/src/util/helpers/helpers.h index 1edc2e19..f4728f28 100644 --- a/src/util/helpers/helpers.h +++ b/src/util/helpers/helpers.h @@ -76,8 +76,6 @@ std::string_view& trim(std::string_view& str, const std::string& chars = "\t\n\v std::string GenerateRandomString(size_t length); std::string GenerateRandomString(size_t length, std::string_view characters); -std::wstring GetSystemErrorMessageW(); -std::wstring GetSystemErrorMessageW(DWORD error_code); std::string GetSystemErrorMessage(); std::string GetSystemErrorMessage(DWORD error_code); std::string GetSystemErrorMessage(const std::exception& ex);