From 1752daeb0882150693f4545a39b43c16e3140b25 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Fri, 19 Jan 2024 16:10:26 -0500 Subject: [PATCH 01/13] Prepare to consolidate strings --- src/libretro/CMakeLists.txt | 1 + src/libretro/strings/en_us.hpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/libretro/strings/en_us.hpp diff --git a/src/libretro/CMakeLists.txt b/src/libretro/CMakeLists.txt index acb80b5e..263a304e 100644 --- a/src/libretro/CMakeLists.txt +++ b/src/libretro/CMakeLists.txt @@ -81,6 +81,7 @@ add_library(melondsds_libretro MODULE std/chrono.hpp std/semaphore.hpp std/span.hpp + strings/en_us.hpp sram.cpp sram.hpp tracy.hpp diff --git a/src/libretro/strings/en_us.hpp b/src/libretro/strings/en_us.hpp new file mode 100644 index 00000000..642c9f0b --- /dev/null +++ b/src/libretro/strings/en_us.hpp @@ -0,0 +1,23 @@ +/* + Copyright 2024 Jesse Talavera + + melonDS DS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS DS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS DS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDSDS_STRINGS_EN_US_HPP +#define MELONDSDS_STRINGS_EN_US_HPP + +namespace MelonDsDs::strings::en_us { +} + +#endif // MELONDSDS_STRINGS_EN_US_HPP From 06e63ed599cc28cbd12b738e7855fdfad20cca2a Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Sat, 20 Jan 2024 11:43:12 -0500 Subject: [PATCH 02/13] Move some strings to a new header --- src/libretro/core/core.cpp | 21 ++++++++------------- src/libretro/strings/en_us.hpp | 11 +++++++++++ src/libretro/strings/strings.hpp | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 src/libretro/strings/strings.hpp diff --git a/src/libretro/core/core.cpp b/src/libretro/core/core.cpp index 3d76d6e2..7f959e37 100644 --- a/src/libretro/core/core.cpp +++ b/src/libretro/core/core.cpp @@ -28,6 +28,7 @@ #include #include +#include "../strings/strings.hpp" #include "../config/console.hpp" #include "../exceptions.hpp" #include "../format.hpp" @@ -44,16 +45,10 @@ using std::span; using namespace melonDS::DSi_NAND; +using namespace MelonDsDs::strings::en_us; constexpr size_t DS_MEMORY_SIZE = 0x400000; constexpr size_t DSI_MEMORY_SIZE = 0x1000000; -static const char* const INTERNAL_ERROR_MESSAGE = - "An internal error occurred with melonDS DS. " - "Please contact the developer with the log file."; - -static const char* const UNKNOWN_ERROR_MESSAGE = - "An unknown error has occurred with melonDS DS. " - "Please contact the developer with the log file."; MelonDsDs::CoreState::~CoreState() noexcept { ZoneScopedN(TracyFunction); @@ -274,7 +269,7 @@ bool MelonDsDs::CoreState::RunDeferredInitialization() noexcept { } catch (...) { retro::error("Deferred initialization failed; exiting core"); - retro::set_error_message(UNKNOWN_ERROR_MESSAGE); + retro::set_error_message(UnknownError); return false; } @@ -464,11 +459,11 @@ catch (const emulator_exception& e) { } catch (const std::exception& e) { retro::error("{}", e.what()); - retro::set_error_message(INTERNAL_ERROR_MESSAGE); + retro::set_error_message(InternalError); return false; } catch (...) { - retro::set_error_message(UNKNOWN_ERROR_MESSAGE); + retro::set_error_message(UnknownError); return false; } @@ -591,14 +586,14 @@ void MelonDsDs::CoreState::InitContent(unsigned type, std::span Date: Fri, 19 Jan 2024 16:10:26 -0500 Subject: [PATCH 03/13] Prepare to consolidate strings --- src/libretro/CMakeLists.txt | 1 + src/libretro/strings/en_us.hpp | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 src/libretro/strings/en_us.hpp diff --git a/src/libretro/CMakeLists.txt b/src/libretro/CMakeLists.txt index acb80b5e..263a304e 100644 --- a/src/libretro/CMakeLists.txt +++ b/src/libretro/CMakeLists.txt @@ -81,6 +81,7 @@ add_library(melondsds_libretro MODULE std/chrono.hpp std/semaphore.hpp std/span.hpp + strings/en_us.hpp sram.cpp sram.hpp tracy.hpp diff --git a/src/libretro/strings/en_us.hpp b/src/libretro/strings/en_us.hpp new file mode 100644 index 00000000..642c9f0b --- /dev/null +++ b/src/libretro/strings/en_us.hpp @@ -0,0 +1,23 @@ +/* + Copyright 2024 Jesse Talavera + + melonDS DS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS DS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS DS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDSDS_STRINGS_EN_US_HPP +#define MELONDSDS_STRINGS_EN_US_HPP + +namespace MelonDsDs::strings::en_us { +} + +#endif // MELONDSDS_STRINGS_EN_US_HPP From 7df037659b3958a605e5bffe968b4dcb461d2d0b Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Sat, 20 Jan 2024 11:43:12 -0500 Subject: [PATCH 04/13] Move some strings to a new header --- src/libretro/core/core.cpp | 21 ++++++++------------- src/libretro/strings/en_us.hpp | 11 +++++++++++ src/libretro/strings/strings.hpp | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 src/libretro/strings/strings.hpp diff --git a/src/libretro/core/core.cpp b/src/libretro/core/core.cpp index 3d76d6e2..7f959e37 100644 --- a/src/libretro/core/core.cpp +++ b/src/libretro/core/core.cpp @@ -28,6 +28,7 @@ #include #include +#include "../strings/strings.hpp" #include "../config/console.hpp" #include "../exceptions.hpp" #include "../format.hpp" @@ -44,16 +45,10 @@ using std::span; using namespace melonDS::DSi_NAND; +using namespace MelonDsDs::strings::en_us; constexpr size_t DS_MEMORY_SIZE = 0x400000; constexpr size_t DSI_MEMORY_SIZE = 0x1000000; -static const char* const INTERNAL_ERROR_MESSAGE = - "An internal error occurred with melonDS DS. " - "Please contact the developer with the log file."; - -static const char* const UNKNOWN_ERROR_MESSAGE = - "An unknown error has occurred with melonDS DS. " - "Please contact the developer with the log file."; MelonDsDs::CoreState::~CoreState() noexcept { ZoneScopedN(TracyFunction); @@ -274,7 +269,7 @@ bool MelonDsDs::CoreState::RunDeferredInitialization() noexcept { } catch (...) { retro::error("Deferred initialization failed; exiting core"); - retro::set_error_message(UNKNOWN_ERROR_MESSAGE); + retro::set_error_message(UnknownError); return false; } @@ -464,11 +459,11 @@ catch (const emulator_exception& e) { } catch (const std::exception& e) { retro::error("{}", e.what()); - retro::set_error_message(INTERNAL_ERROR_MESSAGE); + retro::set_error_message(InternalError); return false; } catch (...) { - retro::set_error_message(UNKNOWN_ERROR_MESSAGE); + retro::set_error_message(UnknownError); return false; } @@ -591,14 +586,14 @@ void MelonDsDs::CoreState::InitContent(unsigned type, std::span Date: Wed, 24 Jan 2024 19:18:59 -0500 Subject: [PATCH 05/13] Move user-facing OSD messages to `en_us.hpp` --- src/libretro/config/config.cpp | 6 ++- src/libretro/config/console.cpp | 26 ++++--------- src/libretro/core/core.cpp | 20 +++------- src/libretro/libretro.cpp | 6 ++- src/libretro/platform/lan.cpp | 4 +- src/libretro/platform/platform.cpp | 6 ++- src/libretro/render/render.cpp | 7 ++-- src/libretro/screenlayout.cpp | 4 +- src/libretro/strings/en_us.hpp | 61 ++++++++++++++++++++++++++++++ 9 files changed, 97 insertions(+), 43 deletions(-) diff --git a/src/libretro/config/config.cpp b/src/libretro/config/config.cpp index 10dcc0d2..1a1d984a 100644 --- a/src/libretro/config/config.cpp +++ b/src/libretro/config/config.cpp @@ -67,12 +67,14 @@ #include "std/span.hpp" #include "tracy.hpp" #include "pcap.hpp" +#include "strings/en_us.hpp" #ifdef interface #undef interface #endif using namespace melonDS; +using namespace MelonDsDs::strings::en_us; using std::array; using std::find_if; using std::from_chars; @@ -780,7 +782,7 @@ bool MelonDsDs::RegisterCoreOptions() noexcept { } } else { - retro::set_error_message("Failed to get system directory, anything that needs it won't work."); + retro::set_error_message(SysDirFailed); } if (!dsiNandPaths.empty()) { @@ -909,7 +911,7 @@ bool MelonDsDs::RegisterCoreOptions() noexcept { #endif if (!retro::set_core_options(optionsUs)) { - retro::set_error_message("Failed to set core option definitions, functionality will be limited."); + retro::set_error_message(OptionInitFailed); return false; } diff --git a/src/libretro/config/console.cpp b/src/libretro/config/console.cpp index 8b1e7d3e..04e32ee0 100644 --- a/src/libretro/config/console.cpp +++ b/src/libretro/config/console.cpp @@ -40,6 +40,7 @@ #include "format.hpp" #include "retro/http.hpp" #include "retro/info.hpp" +#include "strings/strings.hpp" #include "types.hpp" using std::make_optional; @@ -59,6 +60,7 @@ namespace MelonDsDs { const char *TMD_DIR_NAME = "tmd"; const char* SENTINEL_NAME = "melon.dat"; constexpr uint32_t RSA256_SIGNATURE_TYPE = 16777472; + using namespace strings::en_us; static melonDS::NDSArgs GetNdsArgs( const CoreConfig& config, @@ -134,9 +136,7 @@ std::unique_ptr MelonDsDs::CreateConsole( if (type == ConsoleType::DSi) { // If we're in DSi mode... if (gbaInfo || gbaSaveInfo) { - retro::set_warn_message( - "The DSi does not support GBA connectivity. Not loading the requested GBA ROM or SRAM." - ); + retro::set_warn_message(DsiDoesntSupportGbaMode); } return std::make_unique(GetDSiArgs(config, ndsInfo)); } @@ -471,11 +471,7 @@ static std::pair, size_t> MelonDsDs::LoadGbaSram(const ret // We don't support GBA SRAM files in archives right now; // libretro-common has APIs for extracting and re-inserting them, // but I just can't be bothered. - retro::set_error_message( - "melonDS DS does not support archived GBA save data right now. " - "Please extract it and try again. " - "Continuing without using the save data." - ); + retro::set_error_message(ArchivedGbaSaveNotSupported); return { nullptr, 0 }; } @@ -492,11 +488,7 @@ static std::pair, size_t> MelonDsDs::LoadGbaSram(const ret // We don't support rzip-compressed GBA save files right now; // I can't be bothered. - retro::set_error_message( - "melonDS DS does not support compressed GBA save data right now. " - "Please disable save data compression in the frontend and try again. " - "Continuing without using the save data." - ); + retro::set_error_message(CompressedGbaSaveNotSupported); rzipstream_close(gba_save_file); return { nullptr, 0 }; @@ -955,15 +947,13 @@ static void MelonDsDs::CustomizeFirmware(const CoreConfig& config, Firmware& fir memset(&chk2[0x0C], 0, 8); if (!memcmp(chk1, chk2, sizeof(chk1))) { - constexpr const char* const WARNING_MESSAGE = - "Corrupted firmware detected!\n" - "Any game that alters Wi-fi settings will break this firmware, even on real hardware.\n"; + if (config.ShowBiosWarnings()) { - retro::set_warn_message(WARNING_MESSAGE); + retro::set_warn_message(HackedFirmwareWarning); } else { - retro::warn(WARNING_MESSAGE); + retro::warn(HackedFirmwareWarning); } } } diff --git a/src/libretro/core/core.cpp b/src/libretro/core/core.cpp index 7f959e37..eea8a8fd 100644 --- a/src/libretro/core/core.cpp +++ b/src/libretro/core/core.cpp @@ -169,7 +169,7 @@ void MelonDsDs::CoreState::Reset() { ZoneScopedN(TracyFunction); if (_messageScreen) { - retro::set_error_message("Please follow the advice on this screen, then unload/reload the core."); + retro::set_error_message(PleaseResetCore); return; // TODO: Allow the game to be reset from the error screen // (gotta reinitialize the DS here) @@ -362,9 +362,6 @@ void MelonDsDs::CoreState::InitFlushFirmwareTask() noexcept _flushTaskId = flushTask.Identifier(); retro::task::push(std::move(flushTask)); } - else { - retro::set_error_message("System path not found, changes to firmware settings won't be saved."); - } } void MelonDsDs::CoreState::ResetRenderState() { @@ -541,7 +538,7 @@ void MelonDsDs::CoreState::ApplyConfig(const CoreConfig& config) noexcept { // (so that excessive warnings aren't shown) if (!_micState.IsMicInterfaceAvailable() && config.ShowUnsupportedFeatureWarnings()) { // ...but this frontend doesn't support it... - retro::set_warn_message("This frontend doesn't support microphones."); + retro::set_warn_message(MicNotSupported); } else if (!_micState.IsHostMicOpen()) { retro::warn("Failed to open host microphone"); @@ -732,16 +729,11 @@ bool MelonDsDs::CoreState::Unserialize(std::span data) noexcept if (major < SAVESTATE_MAJOR) { // If this savestate is too old... - retro::set_error_message( - "This savestate is too old, can't load it.\n" - "Save your game normally in the older version and import the save data."); + retro::set_error_message(StateTooOld); } else if (major > SAVESTATE_MAJOR) { // If this savestate is too new... - retro::set_error_message( - "This savestate is too new, can't load it.\n" - "Save your game normally in the newer version, " - "then update this core or import the save data."); + retro::set_error_message(StateTooNew); } return false; @@ -749,7 +741,7 @@ bool MelonDsDs::CoreState::Unserialize(std::span data) noexcept if (data.size() != *_savestateSize) { retro::error("Expected a {}-byte savestate, got one of {} bytes", *_savestateSize, data.size()); - retro::set_error_message("Can't load this savestate, most likely the ROM or the core is wrong."); + retro::set_error_message(StateLoadFailed); return false; } @@ -808,7 +800,7 @@ void MelonDsDs::CoreState::CheatSet(unsigned index, bool enabled, std::string_vi return; if (!enabled) { - retro::set_warn_message("Action Replay codes can't be undone, restart the game to remove their effects."); + retro::set_warn_message(CantDisableCheat); return; } diff --git a/src/libretro/libretro.cpp b/src/libretro/libretro.cpp index 5dcfe28b..b2dbd7f8 100644 --- a/src/libretro/libretro.cpp +++ b/src/libretro/libretro.cpp @@ -44,10 +44,12 @@ #include "info.hpp" #include "retro/task_queue.hpp" #include "sram.hpp" +#include "strings/strings.hpp" #include "tracy.hpp" #include "version.hpp" using namespace melonDS; +using namespace MelonDsDs::strings::en_us; using std::make_optional; using std::optional; using std::nullopt; @@ -194,7 +196,7 @@ PUBLIC_SYMBOL void retro_reset(void) { retro::shutdown(); } catch (...) { - retro::set_error_message("An unknown error has occurred."); + retro::set_error_message(UnknownError); retro::shutdown(); } } @@ -280,7 +282,7 @@ void MelonDsDs::HardwareContextReset() noexcept { retro::shutdown(); } catch (...) { - retro::set_error_message("OpenGL context initialization failed with an unknown error. Please report this issue."); + retro::set_error_message(UnknownError); retro::shutdown(); } } diff --git a/src/libretro/platform/lan.cpp b/src/libretro/platform/lan.cpp index e7afacab..04b593d9 100644 --- a/src/libretro/platform/lan.cpp +++ b/src/libretro/platform/lan.cpp @@ -27,9 +27,11 @@ #include "../config/constants.hpp" #include "../config/config.hpp" #include "../environment.hpp" +#include "../strings/strings.hpp" #include "tracy.hpp" #include "pcap.hpp" +using namespace MelonDsDs::strings::en_us; using namespace melonDS; using std::string; using std::string_view; @@ -164,7 +166,7 @@ bool MelonDsDs::CoreState::LanInit() noexcept { return true; } - retro::set_error_message("Failed to initialize indirect-mode Wi-fi support. Wi-fi will not be emulated."); + retro::set_error_message(IndirectWifiInitFailed); [[fallthrough]]; default: _activeNetworkMode = MelonDsDs::NetworkMode::None; diff --git a/src/libretro/platform/platform.cpp b/src/libretro/platform/platform.cpp index b75deba7..3136b8fb 100644 --- a/src/libretro/platform/platform.cpp +++ b/src/libretro/platform/platform.cpp @@ -32,9 +32,11 @@ #include "../format.hpp" #include "retro/scaler.hpp" #include "sram.hpp" +#include "strings/strings.hpp" #include "tracy.hpp" using namespace melonDS; +using namespace MelonDsDs::strings::en_us; constexpr unsigned DSI_CAMERA_WIDTH = 640; constexpr unsigned DSI_CAMERA_HEIGHT = 480; @@ -42,11 +44,11 @@ void Platform::SignalStop(Platform::StopReason reason) { retro::debug("Platform::SignalStop({})\n", reason); switch (reason) { case StopReason::BadExceptionRegion: - retro::set_error_message("An internal error occurred in the emulated console."); + retro::set_error_message(InternalConsoleError); retro::shutdown(); break; case StopReason::GBAModeNotSupported: - retro::set_error_message("GBA mode is not supported. Use a GBA core instead."); + retro::set_error_message(GbaModeNotSupported); retro::shutdown(); break; case StopReason::PowerOff: diff --git a/src/libretro/render/render.cpp b/src/libretro/render/render.cpp index d6ddf93d..841dfcca 100644 --- a/src/libretro/render/render.cpp +++ b/src/libretro/render/render.cpp @@ -26,13 +26,14 @@ #include "message/error.hpp" #include "render/software.hpp" #include "screenlayout.hpp" +#include "strings/en_us.hpp" #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) #include #include "render/opengl.hpp" #endif - +using namespace MelonDsDs::strings::en_us; void MelonDsDs::RenderStateWrapper::Render( melonDS::NDS& nds, const InputState& input, @@ -73,7 +74,7 @@ void MelonDsDs::RenderStateWrapper::SetRenderer(const CoreConfig& config) { break; } - retro::set_warn_message("Failed to initialize OpenGL render state, falling back to software mode."); + retro::set_warn_message(OpenGlInitFailed); [[fallthrough]]; } #endif @@ -115,7 +116,7 @@ void MelonDsDs::RenderStateWrapper::UpdateRenderer(const CoreConfig& config, mel nds.GPU.SetRenderer3D(std::move(renderer)); glRender->RequestRefresh(); } else { - retro::set_warn_message("Failed to initialize OpenGL renderer, falling back to software mode."); + retro::set_warn_message(OpenGlInitFailed); _renderState = std::make_unique(config); nds.GPU.SetRenderer3D(std::make_unique(config.ThreadedSoftRenderer())); } diff --git a/src/libretro/screenlayout.cpp b/src/libretro/screenlayout.cpp index 245cc6c6..44443471 100644 --- a/src/libretro/screenlayout.cpp +++ b/src/libretro/screenlayout.cpp @@ -30,7 +30,9 @@ #include "math.hpp" #include "tracy.hpp" #include "render/render.hpp" +#include "strings/strings.hpp" +using namespace MelonDsDs::strings::en_us; using std::array; using std::max; using glm::inverse; @@ -233,7 +235,7 @@ void MelonDsDs::ScreenLayoutData::Update() noexcept { } else if (newOrientation != retro::ScreenOrientation::Normal) { // A rotation to normal orientation may "fail", even though it's the default. // So only log an error if we're trying to rotate to something besides 0 degrees. - retro::set_error_message("Failed to rotate screen."); + retro::set_error_message(ScreenRotateFailed); } _dirty = false; diff --git a/src/libretro/strings/en_us.hpp b/src/libretro/strings/en_us.hpp index ae186399..2fb82a7a 100644 --- a/src/libretro/strings/en_us.hpp +++ b/src/libretro/strings/en_us.hpp @@ -29,6 +29,67 @@ namespace MelonDsDs::strings::en_us { "Please contact the developer with the log file."; constexpr const char* const InvalidCheat = "Cheat #{} ({:.8}...) isn't valid, ignoring it."; + + constexpr const char* const ArchivedGbaSaveNotSupported = + "melonDS DS does not support archived GBA save data right now. " + "Please extract it and try again. " + "Continuing without using the save data."; + + constexpr const char* const CantDisableCheat = + "Action Replay codes can't be undone, restart the game to disable them."; + + constexpr const char* const CompressedGbaSaveNotSupported = + "melonDS DS does not support compressed GBA save data right now. " + "Please disable save data compression in the frontend and try again. " + "Continuing without using the save data."; + + constexpr const char* const DsiDoesntHaveGbaSlot = + "The DSi doesn't have a GBA slot, " + "please use DS mode instead. " + "Ignoring the loaded GBA ROM."; + + constexpr const char* const GbaModeNotSupported = + "GBA mode is not supported. Use a GBA core instead."; + + constexpr const char* const IndirectWifiInitFailed = + "Failed to initialize indirect-mode Wi-fi support. Wi-fi will be disabled."; + + constexpr const char* const InternalConsoleError = + "An internal error occurred in the emulated console."; + + constexpr const char* const HackedFirmwareWarning = + "Corrupted firmware detected! " + "Any game that alters Wi-fi settings will break this firmware, even on real hardware."; + + constexpr const char* const MicNotSupported = + "This frontend doesn't support microphones."; + + constexpr const char* const OpenGlInitFailed = + "Failed to initialize OpenGL, falling back to software mode."; + + constexpr const char* const OptionInitFailed = + "Failed to set core option definitions, functionality will be limited."; + + constexpr const char* const PleaseResetCore = + "Please follow the advice on this screen, then unload/reload the core."; + + constexpr const char* const ScreenRotateFailed = + "Failed to rotate screen."; + + constexpr const char* const StateTooOld = + "This savestate is too old, can't load it.\n" + "Save your game normally in the older version and import the save data."; + + constexpr const char* const StateTooNew = + "This savestate is too new, can't load it.\n" + "Save your game normally in the newer version, " + "then update this core or import the save data."; + + constexpr const char* const StateLoadFailed = + "Can't load this savestate; did it come from the right core and game?"; + + constexpr const char* const SysDirFailed = + "Failed to get the system directory, functionality will be limited."; } #endif // MELONDSDS_STRINGS_EN_US_HPP From e23f8e966d7d0034635aba3820c06413ca609de2 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Wed, 24 Jan 2024 19:25:16 -0500 Subject: [PATCH 06/13] Move more status messages to string constants --- src/libretro/core/tasks.cpp | 6 ++++-- src/libretro/strings/en_us.hpp | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libretro/core/tasks.cpp b/src/libretro/core/tasks.cpp index ede7c85e..61956b0a 100644 --- a/src/libretro/core/tasks.cpp +++ b/src/libretro/core/tasks.cpp @@ -34,8 +34,10 @@ #include "microphone.hpp" #include "retro/task_queue.hpp" #include "tracy.hpp" +#include "strings/en_us.hpp" using namespace melonDS; +using namespace MelonDsDs::strings::en_us; using std::nullopt; using std::optional; @@ -338,7 +340,7 @@ retro::task::TaskSpec MelonDsDs::CoreState::OnScreenDisplayTask() noexcept { if (Config.ShowCurrentLayout()) { fmt::format_to( inserter, - "{}Layout {}/{}", + CurrentLayout, buf.size() == 0 ? "" : OSD_DELIMITER, _screenLayout.LayoutIndex() + 1, _screenLayout.NumberOfLayouts() @@ -348,7 +350,7 @@ retro::task::TaskSpec MelonDsDs::CoreState::OnScreenDisplayTask() noexcept { if (Config.ShowLidState() && nds.IsLidClosed()) { fmt::format_to( inserter, - "{}Closed", + ScreenState, buf.size() == 0 ? "" : OSD_DELIMITER ); } diff --git a/src/libretro/strings/en_us.hpp b/src/libretro/strings/en_us.hpp index 2fb82a7a..4ace7fbf 100644 --- a/src/libretro/strings/en_us.hpp +++ b/src/libretro/strings/en_us.hpp @@ -90,6 +90,9 @@ namespace MelonDsDs::strings::en_us { constexpr const char* const SysDirFailed = "Failed to get the system directory, functionality will be limited."; + + constexpr const char* const CurrentLayout = "{}Layout {}/{}"; + constexpr const char* const ScreenState = "{}Closed"; } #endif // MELONDSDS_STRINGS_EN_US_HPP From 100b9f2a9199267e639e4acd6e045131df327631 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Wed, 24 Jan 2024 19:30:08 -0500 Subject: [PATCH 07/13] Fix a compiler error --- src/libretro/config/console.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libretro/config/console.cpp b/src/libretro/config/console.cpp index 04e32ee0..6828f2fd 100644 --- a/src/libretro/config/console.cpp +++ b/src/libretro/config/console.cpp @@ -136,7 +136,7 @@ std::unique_ptr MelonDsDs::CreateConsole( if (type == ConsoleType::DSi) { // If we're in DSi mode... if (gbaInfo || gbaSaveInfo) { - retro::set_warn_message(DsiDoesntSupportGbaMode); + retro::set_warn_message(DsiDoesntHaveGbaSlot); } return std::make_unique(GetDSiArgs(config, ndsInfo)); } From 302592cc8f6e6cc6063ccdcb8421248f9b358a3c Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Wed, 24 Jan 2024 21:47:48 -0500 Subject: [PATCH 08/13] Don't split that one sentene in the middle with an `#ifdef` --- src/libretro/config/definitions/network.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/libretro/config/definitions/network.hpp b/src/libretro/config/definitions/network.hpp index 1e31e883..705c33ea 100644 --- a/src/libretro/config/definitions/network.hpp +++ b/src/libretro/config/definitions/network.hpp @@ -31,12 +31,13 @@ namespace MelonDsDs::config::definitions { "Indirect: Use libslirp to emulate the DS's network stack. Simple and needs no setup.\n" #ifdef HAVE_NETWORKING_DIRECT_MODE "Direct: Routes emulated Wi-Fi packets to the host's network interface. " - "Faster and more reliable, but requires an ethernet connection and " -#ifdef _WIN32 - "that WinPcap or Npcap is installed. " -#else - "that libpcap is installed. " -#endif +# ifdef _WIN32 + "Faster and more reliable, but requires an ethernet connection " + "and that WinPcap or Npcap is installed. " +# else + "Faster and more reliable, but requires an ethernet connection " + "and that libpcap is installed. " +# endif "If unavailable, falls back to Indirect mode.\n" #endif "\n" From c5991ee999b3ab6516071bbf727d4a9983ed88dd Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Wed, 24 Jan 2024 21:58:07 -0500 Subject: [PATCH 09/13] Move more string literals to constants --- src/libretro/exceptions.cpp | 22 +++++++--------------- src/libretro/message/error.cpp | 18 ++++++++---------- src/libretro/strings/en_us.hpp | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/libretro/exceptions.cpp b/src/libretro/exceptions.cpp index 7d3a408c..1efc0ebb 100644 --- a/src/libretro/exceptions.cpp +++ b/src/libretro/exceptions.cpp @@ -22,32 +22,24 @@ #include #include +#include "strings/en_us.hpp" + using std::optional; using std::string; using std::string_view; +using namespace MelonDsDs::strings::en_us; MelonDsDs::nds_firmware_not_bootable_exception::nds_firmware_not_bootable_exception(string_view firmwareName) noexcept : bios_exception( - fmt::format( - FMT_STRING( - "The firmware file at \"{}\" can't be used to boot to the DS menu." - ), - firmwareName - ), - "Ensure you have native DS (not DSi) firmware in your frontend's system folder. " - "Pick it in the core options, then restart the core. " - "If you just want to play a DS game, try setting Boot Mode to \"Direct\" " - "or BIOS/Firmware Mode to \"Built-In\" in the core options." + fmt::format(FMT_STRING(NativeFirmwareNotBootableProblem), firmwareName), + FirmwareNotBootableSolution ) { } MelonDsDs::nds_firmware_not_bootable_exception::nds_firmware_not_bootable_exception() noexcept : bios_exception( - "The built-in firmware can't be used to boot to the DS menu.", - "Ensure you have native DS (not DSi) firmware in your frontend's system folder. " - "Pick it in the core options, then restart the core. " - "If you just want to play a DS game, try setting Boot Mode to \"Direct\" " - "or BIOS/Firmware Mode to \"Built-In\" in the core options." + BuiltInFirmwareNotBootableProblem, + FirmwareNotBootableSolution ) { } diff --git a/src/libretro/message/error.cpp b/src/libretro/message/error.cpp index 066229fa..44c69df7 100644 --- a/src/libretro/message/error.cpp +++ b/src/libretro/message/error.cpp @@ -24,6 +24,7 @@ #include "embedded/melondsds_error_title_font.h" #include "embedded/melondsds_error_body_font.h" #include "screenlayout.hpp" +#include "strings/en_us.hpp" #include "tracy.hpp" constexpr int TITLE_FONT_HEIGHT = 20; // in pixels @@ -34,12 +35,9 @@ constexpr pntr_color TEXT_COLOR_TOP = {.rgba = {.b = 0x19, .g = 0x0F, .r = 0xD7, constexpr pntr_color BACKGROUND_COLOR_BOTTOM = {.rgba = {.b = 0x36, .g = 0x7D, .r = 0x63, .a = 0xFF}}; // dark green constexpr pntr_color TEXT_COLOR_BOTTOM = {.rgba = {.b = 0x98, .g = 0xE5, .r = 0xE7, .a = 0xFF}}; // light green -static constexpr const char* const ERROR_TITLE = "Oh no! melonDS DS couldn't start..."; -static constexpr const char* const SOLUTION_TITLE = "Here's what you can do:"; -static constexpr const char* const THANK_YOU = "Thank you for using melonDS DS!"; - using std::span; using MelonDsDs::NDS_SCREEN_AREA; +using namespace MelonDsDs::strings::en_us; // I intentionally fix the error message to the DS screen size to simplify the layout. MelonDsDs::error::ErrorScreen::ErrorScreen(const config_exception& e) noexcept : exception(e) { @@ -101,11 +99,11 @@ void MelonDsDs::error::ErrorScreen::DrawTopScreen(pntr_font* titleFont, pntr_fon pntr_unload_image(errorIcon); // now draw the title - pntr_vector titleTextSize = pntr_measure_text_ex(titleFont, ERROR_TITLE, 0); + pntr_vector titleTextSize = pntr_measure_text_ex(titleFont, ErrorScreenTitle, 0); pntr_draw_text( topScreen, titleFont, - ERROR_TITLE, + ErrorScreenTitle, (NDS_SCREEN_WIDTH - titleTextSize.x) / 2, MARGIN, TEXT_COLOR_TOP @@ -146,11 +144,11 @@ void MelonDsDs::error::ErrorScreen::DrawBottomScreen(pntr_font* titleFont, pntr_ pntr_unload_image(sorryIcon); // now draw the title - pntr_vector titleTextSize = pntr_measure_text_ex(titleFont, SOLUTION_TITLE, 0); + pntr_vector titleTextSize = pntr_measure_text_ex(titleFont, ErrorScreenSolution, 0); pntr_draw_text( bottomScreen, titleFont, - SOLUTION_TITLE, + ErrorScreenSolution, (NDS_SCREEN_WIDTH - titleTextSize.x) / 2, MARGIN, TEXT_COLOR_BOTTOM @@ -167,11 +165,11 @@ void MelonDsDs::error::ErrorScreen::DrawBottomScreen(pntr_font* titleFont, pntr_ TEXT_COLOR_BOTTOM ); - pntr_vector thankYouTextSize = pntr_measure_text_ex(bodyFont, THANK_YOU, 0); + pntr_vector thankYouTextSize = pntr_measure_text_ex(bodyFont, ErrorScreenThanks, 0); pntr_draw_text( bottomScreen, bodyFont, - THANK_YOU, + ErrorScreenThanks, NDS_SCREEN_WIDTH - thankYouTextSize.x - MARGIN, NDS_SCREEN_HEIGHT - thankYouTextSize.y - MARGIN, TEXT_COLOR_BOTTOM diff --git a/src/libretro/strings/en_us.hpp b/src/libretro/strings/en_us.hpp index 4ace7fbf..f8748723 100644 --- a/src/libretro/strings/en_us.hpp +++ b/src/libretro/strings/en_us.hpp @@ -93,6 +93,22 @@ namespace MelonDsDs::strings::en_us { constexpr const char* const CurrentLayout = "{}Layout {}/{}"; constexpr const char* const ScreenState = "{}Closed"; + + constexpr const char* const ErrorScreenTitle = "Oh no! melonDS DS couldn't start..."; + constexpr const char* const ErrorScreenSolution = "Here's what you can do:"; + constexpr const char* const ErrorScreenThanks = "Thank you for using melonDS DS!"; + + constexpr const char* const NativeFirmwareNotBootableProblem = + "The firmware file at \"{}\" can't be used to boot to the DS menu."; + + constexpr const char* const BuiltInFirmwareNotBootableProblem = + "The firmware file at \"{}\" can't be used to boot to the DS menu."; + + constexpr const char* const FirmwareNotBootableSolution = + "Ensure you have native DS (not DSi) firmware in your frontend's system folder. " + "Pick it in the core options, then restart the core. " + "If you just want to play a DS game, try setting Boot Mode to \"Direct\" " + "or BIOS/Firmware Mode to \"Built-In\" in the core options."; } #endif // MELONDSDS_STRINGS_EN_US_HPP From b269c927973ef1909121af6d80432e37cbf8fc56 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Tue, 30 Jan 2024 15:33:27 -0500 Subject: [PATCH 10/13] Split the strings into different header files --- src/libretro/CMakeLists.txt | 3 + src/libretro/strings/en_us.hpp | 95 ++------------------------- src/libretro/strings/en_us/error.hpp | 39 +++++++++++ src/libretro/strings/en_us/notice.hpp | 94 ++++++++++++++++++++++++++ src/libretro/strings/en_us/osd.hpp | 26 ++++++++ 5 files changed, 166 insertions(+), 91 deletions(-) create mode 100644 src/libretro/strings/en_us/error.hpp create mode 100644 src/libretro/strings/en_us/notice.hpp create mode 100644 src/libretro/strings/en_us/osd.hpp diff --git a/src/libretro/CMakeLists.txt b/src/libretro/CMakeLists.txt index 263a304e..19db210d 100644 --- a/src/libretro/CMakeLists.txt +++ b/src/libretro/CMakeLists.txt @@ -82,6 +82,9 @@ add_library(melondsds_libretro MODULE std/semaphore.hpp std/span.hpp strings/en_us.hpp + strings/en_us/error.hpp + strings/en_us/notice.hpp + strings/en_us/osd.hpp sram.cpp sram.hpp tracy.hpp diff --git a/src/libretro/strings/en_us.hpp b/src/libretro/strings/en_us.hpp index f8748723..f6bd0164 100644 --- a/src/libretro/strings/en_us.hpp +++ b/src/libretro/strings/en_us.hpp @@ -17,98 +17,11 @@ #ifndef MELONDSDS_STRINGS_EN_US_HPP #define MELONDSDS_STRINGS_EN_US_HPP +#include "en_us/error.hpp" +#include "en_us/notice.hpp" +#include "en_us/osd.hpp" + // These strings are intended to be shown directly to the player; // log messages don't need to be declared here. -namespace MelonDsDs::strings::en_us { - constexpr const char* const InternalError = - "An internal error occurred with melonDS DS. " - "Please contact the developer with the log file."; - - constexpr const char* const UnknownError = - "An unknown error has occurred with melonDS DS. " - "Please contact the developer with the log file."; - - constexpr const char* const InvalidCheat = "Cheat #{} ({:.8}...) isn't valid, ignoring it."; - - constexpr const char* const ArchivedGbaSaveNotSupported = - "melonDS DS does not support archived GBA save data right now. " - "Please extract it and try again. " - "Continuing without using the save data."; - - constexpr const char* const CantDisableCheat = - "Action Replay codes can't be undone, restart the game to disable them."; - - constexpr const char* const CompressedGbaSaveNotSupported = - "melonDS DS does not support compressed GBA save data right now. " - "Please disable save data compression in the frontend and try again. " - "Continuing without using the save data."; - - constexpr const char* const DsiDoesntHaveGbaSlot = - "The DSi doesn't have a GBA slot, " - "please use DS mode instead. " - "Ignoring the loaded GBA ROM."; - - constexpr const char* const GbaModeNotSupported = - "GBA mode is not supported. Use a GBA core instead."; - - constexpr const char* const IndirectWifiInitFailed = - "Failed to initialize indirect-mode Wi-fi support. Wi-fi will be disabled."; - - constexpr const char* const InternalConsoleError = - "An internal error occurred in the emulated console."; - - constexpr const char* const HackedFirmwareWarning = - "Corrupted firmware detected! " - "Any game that alters Wi-fi settings will break this firmware, even on real hardware."; - - constexpr const char* const MicNotSupported = - "This frontend doesn't support microphones."; - - constexpr const char* const OpenGlInitFailed = - "Failed to initialize OpenGL, falling back to software mode."; - - constexpr const char* const OptionInitFailed = - "Failed to set core option definitions, functionality will be limited."; - - constexpr const char* const PleaseResetCore = - "Please follow the advice on this screen, then unload/reload the core."; - - constexpr const char* const ScreenRotateFailed = - "Failed to rotate screen."; - - constexpr const char* const StateTooOld = - "This savestate is too old, can't load it.\n" - "Save your game normally in the older version and import the save data."; - - constexpr const char* const StateTooNew = - "This savestate is too new, can't load it.\n" - "Save your game normally in the newer version, " - "then update this core or import the save data."; - - constexpr const char* const StateLoadFailed = - "Can't load this savestate; did it come from the right core and game?"; - - constexpr const char* const SysDirFailed = - "Failed to get the system directory, functionality will be limited."; - - constexpr const char* const CurrentLayout = "{}Layout {}/{}"; - constexpr const char* const ScreenState = "{}Closed"; - - constexpr const char* const ErrorScreenTitle = "Oh no! melonDS DS couldn't start..."; - constexpr const char* const ErrorScreenSolution = "Here's what you can do:"; - constexpr const char* const ErrorScreenThanks = "Thank you for using melonDS DS!"; - - constexpr const char* const NativeFirmwareNotBootableProblem = - "The firmware file at \"{}\" can't be used to boot to the DS menu."; - - constexpr const char* const BuiltInFirmwareNotBootableProblem = - "The firmware file at \"{}\" can't be used to boot to the DS menu."; - - constexpr const char* const FirmwareNotBootableSolution = - "Ensure you have native DS (not DSi) firmware in your frontend's system folder. " - "Pick it in the core options, then restart the core. " - "If you just want to play a DS game, try setting Boot Mode to \"Direct\" " - "or BIOS/Firmware Mode to \"Built-In\" in the core options."; -} #endif // MELONDSDS_STRINGS_EN_US_HPP diff --git a/src/libretro/strings/en_us/error.hpp b/src/libretro/strings/en_us/error.hpp new file mode 100644 index 00000000..c5af1bc5 --- /dev/null +++ b/src/libretro/strings/en_us/error.hpp @@ -0,0 +1,39 @@ +/* + Copyright 2024 Jesse Talavera + + melonDS DS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS DS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS DS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDSDS_STRINGS_EN_US_ERROR_HPP +#define MELONDSDS_STRINGS_EN_US_ERROR_HPP + +// For messages that are meant to be displayed on the error screen +namespace MelonDsDs::strings::en_us { + constexpr const char* const ErrorScreenTitle = "Oh no! melonDS DS couldn't start..."; + constexpr const char* const ErrorScreenSolution = "Here's what you can do:"; + constexpr const char* const ErrorScreenThanks = "Thank you for using melonDS DS!"; + + constexpr const char* const NativeFirmwareNotBootableProblem = + "The firmware file at \"{}\" can't be used to boot to the DS menu."; + + constexpr const char* const BuiltInFirmwareNotBootableProblem = + "The firmware file at \"{}\" can't be used to boot to the DS menu."; + + constexpr const char* const FirmwareNotBootableSolution = + "Ensure you have native DS (not DSi) firmware in your frontend's system folder. " + "Pick it in the core options, then restart the core. " + "If you just want to play a DS game, try setting Boot Mode to \"Direct\" " + "or BIOS/Firmware Mode to \"Built-In\" in the core options."; +} + +#endif //MELONDSDS_STRINGS_EN_US_ERROR_HPP diff --git a/src/libretro/strings/en_us/notice.hpp b/src/libretro/strings/en_us/notice.hpp new file mode 100644 index 00000000..c0465ca0 --- /dev/null +++ b/src/libretro/strings/en_us/notice.hpp @@ -0,0 +1,94 @@ +/* + Copyright 2024 Jesse Talavera + + melonDS DS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS DS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS DS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDSDS_STRINGS_EN_US_NOTICE_HPP +#define MELONDSDS_STRINGS_EN_US_NOTICE_HPP + +// For strings that are meant to be briefly displayed as on-screen notices +namespace MelonDsDs::strings::en_us { + constexpr const char* const InternalError = + "An internal error occurred with melonDS DS. " + "Please contact the developer with the log file."; + + constexpr const char* const UnknownError = + "An unknown error has occurred with melonDS DS. " + "Please contact the developer with the log file."; + + constexpr const char* const InvalidCheat = "Cheat #{} ({:.8}...) isn't valid, ignoring it."; + + constexpr const char* const ArchivedGbaSaveNotSupported = + "melonDS DS does not support archived GBA save data right now. " + "Please extract it and try again. " + "Continuing without using the save data."; + + constexpr const char* const CantDisableCheat = + "Action Replay codes can't be undone, restart the game to disable them."; + + constexpr const char* const CompressedGbaSaveNotSupported = + "melonDS DS does not support compressed GBA save data right now. " + "Please disable save data compression in the frontend and try again. " + "Continuing without using the save data."; + + constexpr const char* const DsiDoesntHaveGbaSlot = + "The DSi doesn't have a GBA slot, " + "please use DS mode instead. " + "Ignoring the loaded GBA ROM."; + + constexpr const char* const GbaModeNotSupported = + "GBA mode is not supported. Use a GBA core instead."; + + constexpr const char* const IndirectWifiInitFailed = + "Failed to initialize indirect-mode Wi-fi support. Wi-fi will be disabled."; + + constexpr const char* const InternalConsoleError = + "An internal error occurred in the emulated console."; + + constexpr const char* const HackedFirmwareWarning = + "Corrupted firmware detected! " + "Any game that alters Wi-fi settings will break this firmware, even on real hardware."; + + constexpr const char* const MicNotSupported = + "This frontend doesn't support microphones."; + + constexpr const char* const OpenGlInitFailed = + "Failed to initialize OpenGL, falling back to software mode."; + + constexpr const char* const OptionInitFailed = + "Failed to set core option definitions, functionality will be limited."; + + constexpr const char* const PleaseResetCore = + "Please follow the advice on this screen, then unload/reload the core."; + + constexpr const char* const ScreenRotateFailed = + "Failed to rotate screen."; + + constexpr const char* const StateTooOld = + "This savestate is too old, can't load it.\n" + "Save your game normally in the older version and import the save data."; + + constexpr const char* const StateTooNew = + "This savestate is too new, can't load it.\n" + "Save your game normally in the newer version, " + "then update this core or import the save data."; + + constexpr const char* const StateLoadFailed = + "Can't load this savestate; did it come from the right core and game?"; + + constexpr const char* const SysDirFailed = + "Failed to get the system directory, functionality will be limited."; +} + +#endif //MELONDSDS_STRINGS_EN_US_NOTICE_HPP diff --git a/src/libretro/strings/en_us/osd.hpp b/src/libretro/strings/en_us/osd.hpp new file mode 100644 index 00000000..bac970ca --- /dev/null +++ b/src/libretro/strings/en_us/osd.hpp @@ -0,0 +1,26 @@ +/* + Copyright 2024 Jesse Talavera + + melonDS DS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS DS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS DS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef MELONDSDS_STRINGS_EN_US_OSD_HPP +#define MELONDSDS_STRINGS_EN_US_OSD_HPP + +// For strings that are meant to be displayed on the on-screen status display +namespace MelonDsDs::strings::en_us { + constexpr const char* const CurrentLayout = "{}Layout {}/{}"; + constexpr const char* const ScreenState = "{}Closed"; +} + +#endif //MELONDSDS_STRINGS_EN_US_OSD_HPP From 360da8e99638c5d59a7b7d24032430434e9a6cf1 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Tue, 30 Jan 2024 17:08:11 -0500 Subject: [PATCH 11/13] Move more string constants to the new headers --- src/libretro/core/core.cpp | 6 +-- src/libretro/exceptions.cpp | 75 +++++++-------------------- src/libretro/strings/en_us/error.hpp | 73 +++++++++++++++++++++++++- src/libretro/strings/en_us/notice.hpp | 3 ++ 4 files changed, 95 insertions(+), 62 deletions(-) diff --git a/src/libretro/core/core.cpp b/src/libretro/core/core.cpp index eea8a8fd..f8abd78f 100644 --- a/src/libretro/core/core.cpp +++ b/src/libretro/core/core.cpp @@ -379,8 +379,7 @@ bool MelonDsDs::CoreState::LoadGame(unsigned type, std::span Date: Tue, 13 Feb 2024 10:25:50 -0500 Subject: [PATCH 12/13] Move some newly-introduced strings to the header files --- src/libretro/config/console.cpp | 2 +- src/libretro/strings/en_us/notice.hpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libretro/config/console.cpp b/src/libretro/config/console.cpp index 6828f2fd..0cfafaf5 100644 --- a/src/libretro/config/console.cpp +++ b/src/libretro/config/console.cpp @@ -971,7 +971,7 @@ static void MelonDsDs::CustomizeFirmware(const CoreConfig& config, Firmware& fir optional convertedUsername = ConvertUsername(*username); if (!convertedUsername) { - retro::set_warn_message("Can't use the name \"{}\" on the DS, using default name instead.", *username); + retro::set_warn_message(UsernameFailed, *username); convertedUsername = ConvertUsername(config::values::firmware::DEFAULT_USERNAME); } diff --git a/src/libretro/strings/en_us/notice.hpp b/src/libretro/strings/en_us/notice.hpp index dde12c3f..4c952dce 100644 --- a/src/libretro/strings/en_us/notice.hpp +++ b/src/libretro/strings/en_us/notice.hpp @@ -92,6 +92,12 @@ namespace MelonDsDs::strings::en_us { constexpr const char* const SysDirFailed = "Failed to get the system directory, functionality will be limited."; + + constexpr const char* const UsernameFailed = + "Can't use the name \"{}\" on the DS, using default name instead."; + + constexpr const char* const UsernameUnavailable = + "Failed to get username, or none was provided; using default"; } #endif //MELONDSDS_STRINGS_EN_US_NOTICE_HPP From d7a8a7bc71434814e063ffc071f158d9d8ba22a4 Mon Sep 17 00:00:00 2001 From: Jesse Talavera Date: Wed, 14 Feb 2024 13:31:56 -0500 Subject: [PATCH 13/13] Use named format arguments for user-facing strings - Oughta simplify things for translators --- src/libretro/config/console.cpp | 2 +- src/libretro/core/core.cpp | 2 +- src/libretro/core/tasks.cpp | 8 ++-- src/libretro/exceptions.cpp | 55 ++++++++++++++------------- src/libretro/exceptions.hpp | 2 +- src/libretro/strings/en_us/error.hpp | 24 ++++++------ src/libretro/strings/en_us/notice.hpp | 4 +- src/libretro/strings/en_us/osd.hpp | 4 +- 8 files changed, 51 insertions(+), 50 deletions(-) diff --git a/src/libretro/config/console.cpp b/src/libretro/config/console.cpp index 0cfafaf5..cb9a8bd5 100644 --- a/src/libretro/config/console.cpp +++ b/src/libretro/config/console.cpp @@ -971,7 +971,7 @@ static void MelonDsDs::CustomizeFirmware(const CoreConfig& config, Firmware& fir optional convertedUsername = ConvertUsername(*username); if (!convertedUsername) { - retro::set_warn_message(UsernameFailed, *username); + retro::set_warn_message(UsernameFailed, fmt::arg("name", *username)); convertedUsername = ConvertUsername(config::values::firmware::DEFAULT_USERNAME); } diff --git a/src/libretro/core/core.cpp b/src/libretro/core/core.cpp index 234245e7..61cf6ccf 100644 --- a/src/libretro/core/core.cpp +++ b/src/libretro/core/core.cpp @@ -866,7 +866,7 @@ void MelonDsDs::CoreState::CheatSet(unsigned index, bool enabled, std::string_vi if (!regex_match(code.data(), _cheatSyntax)) { // If we're trying to activate this cheat code, but it's not valid... - retro::set_warn_message(InvalidCheat, index, code); + retro::set_warn_message(InvalidCheat, fmt::arg("index", index), fmt::arg("code", code)); return; } diff --git a/src/libretro/core/tasks.cpp b/src/libretro/core/tasks.cpp index 61956b0a..347a80c7 100644 --- a/src/libretro/core/tasks.cpp +++ b/src/libretro/core/tasks.cpp @@ -341,9 +341,9 @@ retro::task::TaskSpec MelonDsDs::CoreState::OnScreenDisplayTask() noexcept { fmt::format_to( inserter, CurrentLayout, - buf.size() == 0 ? "" : OSD_DELIMITER, - _screenLayout.LayoutIndex() + 1, - _screenLayout.NumberOfLayouts() + fmt::arg("sep", buf.size() == 0 ? "" : OSD_DELIMITER), + fmt::arg("layout_num", _screenLayout.LayoutIndex() + 1), + fmt::arg("num_layouts", _screenLayout.NumberOfLayouts()) ); } @@ -351,7 +351,7 @@ retro::task::TaskSpec MelonDsDs::CoreState::OnScreenDisplayTask() noexcept { fmt::format_to( inserter, ScreenState, - buf.size() == 0 ? "" : OSD_DELIMITER + fmt::arg("sep", buf.size() == 0 ? "" : OSD_DELIMITER) ); } diff --git a/src/libretro/exceptions.cpp b/src/libretro/exceptions.cpp index 3a592bc3..86fd23a2 100644 --- a/src/libretro/exceptions.cpp +++ b/src/libretro/exceptions.cpp @@ -28,10 +28,11 @@ using std::optional; using std::string; using std::string_view; using namespace MelonDsDs::strings::en_us; +using fmt::arg; -MelonDsDs::nds_firmware_not_bootable_exception::nds_firmware_not_bootable_exception(string_view firmwareName) noexcept +MelonDsDs::nds_firmware_not_bootable_exception::nds_firmware_not_bootable_exception(string_view path) noexcept : bios_exception( - fmt::format(NativeFirmwareNotBootableProblem, firmwareName), + fmt::format(NativeFirmwareNotBootableProblem, arg("path", path)), FirmwareNotBootableSolution ) { } @@ -44,35 +45,35 @@ MelonDsDs::nds_firmware_not_bootable_exception::nds_firmware_not_bootable_except } MelonDsDs::wrong_firmware_type_exception::wrong_firmware_type_exception( - std::string_view firmwareName, - MelonDsDs::ConsoleType consoleType, - melonDS::Firmware::FirmwareConsoleType firmwareConsoleType + std::string_view path, + MelonDsDs::ConsoleType console, + melonDS::Firmware::FirmwareConsoleType firmwareConsole ) noexcept : bios_exception( fmt::format( WrongFirmwareProblem, - firmwareName, - firmwareConsoleType, - consoleType + arg("path", path), + arg("firmwareConsole", firmwareConsole), + arg("console", console) ), fmt::format( WrongFirmwareSolution, - consoleType + arg("console", console) ) ) { } MelonDsDs::dsi_region_mismatch_exception::dsi_region_mismatch_exception( - string_view nandName, - melonDS::DSi_NAND::ConsoleRegion nandRegion, - melonDS::RegionMask gameRegionMask + string_view path, + melonDS::DSi_NAND::ConsoleRegion region, + melonDS::RegionMask regions ) noexcept : config_exception( fmt::format( WrongNandRegionProblem, - nandName, - nandRegion, - gameRegionMask + arg("path", path), + arg("region", region), + arg("regions", regions) ), WrongNandRegionSolution ) { @@ -85,10 +86,10 @@ MelonDsDs::dsi_no_firmware_found_exception::dsi_no_firmware_found_exception() no ) { } -MelonDsDs::firmware_missing_exception::firmware_missing_exception(std::string_view firmwareName) noexcept +MelonDsDs::firmware_missing_exception::firmware_missing_exception(std::string_view path) noexcept : bios_exception( - fmt::format(NoFirmwareProblem, firmwareName), - fmt::format(NoFirmwareSolution, firmwareName) + fmt::format(NoFirmwareProblem, arg("path", path)), + fmt::format(NoFirmwareSolution, arg("path", path)) ) { } @@ -99,13 +100,13 @@ MelonDsDs::nds_sysfiles_incomplete_exception::nds_sysfiles_incomplete_exception( ) { } -MelonDsDs::dsi_missing_bios_exception::dsi_missing_bios_exception(MelonDsDs::BiosType bios, string_view biosName) noexcept +MelonDsDs::dsi_missing_bios_exception::dsi_missing_bios_exception(MelonDsDs::BiosType bios, string_view path) noexcept : bios_exception( - fmt::format(MissingDsiBiosProblem, bios), + fmt::format(MissingDsiBiosProblem, arg("bios", bios)), fmt::format( MissingDsiBiosSolution, - bios, - biosName + arg("bios", bios), + arg("path", path) ) ) { } @@ -117,16 +118,16 @@ MelonDsDs::dsi_no_nand_found_exception::dsi_no_nand_found_exception() noexcept ) { } -MelonDsDs::dsi_nand_missing_exception::dsi_nand_missing_exception(string_view nandName) noexcept +MelonDsDs::dsi_nand_missing_exception::dsi_nand_missing_exception(string_view path) noexcept : bios_exception( - fmt::format(MissingDsiNandProblem, nandName), - fmt::format(MissingDsiNandSolution, nandName) + fmt::format(MissingDsiNandProblem, arg("path", path)), + fmt::format(MissingDsiNandSolution, arg("path", path)) ) { } -MelonDsDs::dsi_nand_corrupted_exception::dsi_nand_corrupted_exception(string_view nandName) noexcept +MelonDsDs::dsi_nand_corrupted_exception::dsi_nand_corrupted_exception(string_view path) noexcept : bios_exception( - fmt::format(CorruptDsiNandProblem, nandName), + fmt::format(CorruptDsiNandProblem, arg("path", path)), CorruptDsiNandSolution ) { } diff --git a/src/libretro/exceptions.hpp b/src/libretro/exceptions.hpp index c13ac2dd..e498a97e 100644 --- a/src/libretro/exceptions.hpp +++ b/src/libretro/exceptions.hpp @@ -97,7 +97,7 @@ namespace MelonDsDs class nds_firmware_not_bootable_exception : public bios_exception { public: explicit nds_firmware_not_bootable_exception() noexcept; - explicit nds_firmware_not_bootable_exception(std::string_view firmwareName) noexcept; + explicit nds_firmware_not_bootable_exception(std::string_view path) noexcept; }; diff --git a/src/libretro/strings/en_us/error.hpp b/src/libretro/strings/en_us/error.hpp index f7b12ccb..68c84e0e 100644 --- a/src/libretro/strings/en_us/error.hpp +++ b/src/libretro/strings/en_us/error.hpp @@ -24,7 +24,7 @@ namespace MelonDsDs::strings::en_us { constexpr const char* const ErrorScreenThanks = "Thank you for using melonDS DS!"; constexpr const char* const NativeFirmwareNotBootableProblem = - "The firmware file at \"{}\" can't be used to boot to the DS menu."; + "The firmware file at \"{path}\" can't be used to boot to the DS menu."; constexpr const char* const BuiltInFirmwareNotBootableProblem = "The built-in firmware can't be used to boot to the DS menu."; @@ -36,16 +36,16 @@ namespace MelonDsDs::strings::en_us { "or BIOS/Firmware Mode to \"Built-In\" in the core options."; constexpr const char* const WrongFirmwareProblem = - "The firmware file at \"{}\" is for the {}, but it can't be used in {} mode."; + "The firmware file at \"{path}\" is for the {firmwareConsole}, but it can't be used in {console} mode."; constexpr const char* const WrongFirmwareSolution = - "Ensure you have a {}-compatible firmware file in your frontend's system folder (any name works). " + "Ensure you have a {console}-compatible firmware file in your frontend's system folder (any name works). " "Pick it in the core options, then restart the core. " "If you just want to play a DS game, try disabling DSi mode in the core options."; constexpr const char* const WrongNandRegionProblem = - "The NAND file at \"{}\" has the region \"{}\", " - "but the loaded DSiWare game will only run in the following regions: {}"; + "The NAND file at \"{path}\" has the region \"{region}\", " + "but the loaded DSiWare game will only run in the following regions: {regions}"; constexpr const char* const WrongNandRegionSolution = "Double-check that you're using the right NAND file " @@ -61,10 +61,10 @@ namespace MelonDsDs::strings::en_us { "try disabling DSi mode in the core options."; constexpr const char* const NoFirmwareProblem = - "The core is set to use the firmware file at \"{}\", but it wasn't there or it couldn't be loaded."; + "The core is set to use the firmware file at \"{path}\", but it wasn't there or it couldn't be loaded."; constexpr const char* const NoFirmwareSolution = - "Place your DSi firmware file in your frontend's system folder, name it \"{}\", then restart the core."; + "Place your DSi firmware file in your frontend's system folder, name it \"{path}\", then restart the core."; constexpr const char* const IncompleteNdsSysfilesProblem = "Booting to the native DS menu requires native DS firmware and BIOS files, " @@ -76,10 +76,10 @@ namespace MelonDsDs::strings::en_us { "and BIOS/Firmware Mode to \"Built-In\" in the core options."; constexpr const char* const MissingDsiBiosProblem = - "DSi mode requires the {} BIOS file, but none was found."; + "DSi mode requires the {bios} BIOS file, but none was found."; constexpr const char* const MissingDsiBiosSolution = - "Place your {} BIOS file in your frontend's system folder, name it \"{}\", then restart the core. " + "Place your {bios} BIOS file in your frontend's system folder, name it \"{path}\", then restart the core. " "If you want to play a regular DS game, try disabling DSi mode in the core options."; constexpr const char* const NoDsiNandProblem = @@ -91,14 +91,14 @@ namespace MelonDsDs::strings::en_us { "If you want to play a regular DS game, try disabling DSi mode in the core options."; constexpr const char* const MissingDsiNandProblem = - "The core is set to use the NAND file at \"{}\", but it wasn't there or it couldn't be loaded."; + "The core is set to use the NAND file at \"{path}\", but it wasn't there or it couldn't be loaded."; constexpr const char* const MissingDsiNandSolution = - "Place your NAND file in your frontend's system folder, name it \"{}\", then restart the core. " + "Place your NAND file in your frontend's system folder, name it \"{path}\", then restart the core. " "If you've already done that, ensure that you're using the right NAND file."; constexpr const char* const CorruptDsiNandProblem = - "The core managed to load the configured NAND file at \"{}\", " + "The core managed to load the configured NAND file at \"{path}\", " "but it seems to be corrupted or invalid."; constexpr const char* const CorruptDsiNandSolution = diff --git a/src/libretro/strings/en_us/notice.hpp b/src/libretro/strings/en_us/notice.hpp index 4c952dce..52ffbb5c 100644 --- a/src/libretro/strings/en_us/notice.hpp +++ b/src/libretro/strings/en_us/notice.hpp @@ -27,7 +27,7 @@ namespace MelonDsDs::strings::en_us { "An unknown error has occurred with melonDS DS. " "Please contact the developer with the log file."; - constexpr const char* const InvalidCheat = "Cheat #{} ({:.8}...) isn't valid, ignoring it."; + constexpr const char* const InvalidCheat = "Cheat #{index} ({code:.8}...) isn't valid, ignoring it."; constexpr const char* const ArchivedGbaSaveNotSupported = "melonDS DS does not support archived GBA save data right now. " @@ -94,7 +94,7 @@ namespace MelonDsDs::strings::en_us { "Failed to get the system directory, functionality will be limited."; constexpr const char* const UsernameFailed = - "Can't use the name \"{}\" on the DS, using default name instead."; + "Can't use the name \"{name}\" on the DS, using default name instead."; constexpr const char* const UsernameUnavailable = "Failed to get username, or none was provided; using default"; diff --git a/src/libretro/strings/en_us/osd.hpp b/src/libretro/strings/en_us/osd.hpp index bac970ca..01a53db1 100644 --- a/src/libretro/strings/en_us/osd.hpp +++ b/src/libretro/strings/en_us/osd.hpp @@ -19,8 +19,8 @@ // For strings that are meant to be displayed on the on-screen status display namespace MelonDsDs::strings::en_us { - constexpr const char* const CurrentLayout = "{}Layout {}/{}"; - constexpr const char* const ScreenState = "{}Closed"; + constexpr const char* const CurrentLayout = "{sep}Layout {layout_num}/{num_layouts}"; + constexpr const char* const ScreenState = "{sep}Closed"; } #endif //MELONDSDS_STRINGS_EN_US_OSD_HPP