mirror of
https://github.com/grumpycoders/pcsx-redux.git
synced 2026-10-12 02:15:13 +00:00
Merge pull request #2207 from rixnobis/i18n-ctx
i18n: msgctxt support, fewer untranslatable strings, fuzzy fix
This commit is contained in:
@@ -393,7 +393,7 @@ endef
|
||||
|
||||
regen-i18n:
|
||||
find src -name *.cc -or -name *.c -or -name *.h | sort -u > pcsx-src-list.txt
|
||||
xgettext --from-code=utf-8 --keyword=_ --keyword=f_ --keyword=l_ --language=C++ --add-comments --sort-by-file -o i18n/pcsx-redux.pot -f pcsx-src-list.txt
|
||||
xgettext --from-code=utf-8 --keyword=_ --keyword=f_ --keyword=l_ --keyword=C_:1c,2 --keyword=lC_:1c,2 --language=C++ --add-comments --sort-by-file -o i18n/pcsx-redux.pot -f pcsx-src-list.txt
|
||||
find src -name *.lua | sort -u > pcsx-src-list.txt
|
||||
xgettext --from-code=utf-8 --keyword=t_ --language=Lua --join-existing --sort-by-file -o i18n/pcsx-redux.pot -f pcsx-src-list.txt
|
||||
sed '/POT-Creation-Date/d' -i i18n/pcsx-redux.pot
|
||||
|
||||
@@ -478,7 +478,7 @@ bool PCSX::OpenGL_GPU::configure() {
|
||||
int msaaSampleCount = g_emulator->settings.get<Emulator::SettingMSAA>();
|
||||
const auto msaaString = msaaSampleCount == 1 ? _("No MSAA") : fmt::format(f_("{}x MSAA"), msaaSampleCount);
|
||||
|
||||
if (ImGui::BeginCombo(_("MSAA"), msaaString.c_str())) {
|
||||
if (ImGui::BeginCombo("MSAA", msaaString.c_str())) {
|
||||
const int maxMSAA = OpenGL::maxSamples();
|
||||
|
||||
if (ImGui::Selectable(_("No MSAA"))) {
|
||||
|
||||
+2
-1
@@ -35,7 +35,8 @@ class Debug {
|
||||
Debug();
|
||||
static uint32_t normalizeAddress(uint32_t address);
|
||||
static bool isInKernel(uint32_t address, bool biosIsKernel = true);
|
||||
static inline std::function<const char*()> s_breakpoint_type_names[] = {l_("Exec"), l_("Read"), l_("Write")};
|
||||
static inline std::function<const char*()> s_breakpoint_type_names[] = {
|
||||
lC_("Breakpoint type", "Exec"), lC_("Breakpoint type", "Read"), lC_("Breakpoint type", "Write")};
|
||||
enum class BreakpointType { Exec, Read, Write };
|
||||
enum class BreakpointCondition { Always, Change, Greater, Less, Equal };
|
||||
|
||||
|
||||
@@ -434,7 +434,8 @@ void PCSX::GPU::DrawingAreaEnd::drawLogNode(unsigned, const DrawLogSettings&) {
|
||||
void PCSX::GPU::DrawingOffset::drawLogNode(unsigned, const DrawLogSettings&) { ImGui::Text(" X: %i, Y: %i", x, y); }
|
||||
|
||||
void PCSX::GPU::MaskBit::drawLogNode(unsigned, const DrawLogSettings&) {
|
||||
ImGui::Text(_(" Set: %s, Check: %s"), set ? _("Yes") : _("No"), check ? _("Yes") : _("No"));
|
||||
ImGui::Text(" %s",
|
||||
fmt::format(f_("Set: {}, Check: {}"), set ? _("Yes") : _("No"), check ? _("Yes") : _("No")).c_str());
|
||||
}
|
||||
|
||||
void PCSX::GPU::CtrlReset::drawLogNode(unsigned, const DrawLogSettings&) {}
|
||||
|
||||
+17
-6
@@ -1035,14 +1035,25 @@ bool PadsImpl::Pad::configure() {
|
||||
l_("Keyboard"),
|
||||
};
|
||||
static std::function<const char*()> const c_buttonNames[] = {
|
||||
l_("╳"), l_("□"), l_("△"), l_("◯"), l_("Select"), l_("Start"), l_("L1"),
|
||||
l_("R1"), l_("L2"), l_("R2"), l_("L3"), l_("R3"), l_("Analog Mode"),
|
||||
[]() { return "╳"; },
|
||||
[]() { return "□"; },
|
||||
[]() { return "△"; },
|
||||
[]() { return "◯"; },
|
||||
lC_("Controller button", "Select"),
|
||||
lC_("Controller button", "Start"),
|
||||
[]() { return "L1"; },
|
||||
[]() { return "R1"; },
|
||||
[]() { return "L2"; },
|
||||
[]() { return "R2"; },
|
||||
[]() { return "L3"; },
|
||||
[]() { return "R3"; },
|
||||
l_("Analog Mode"),
|
||||
};
|
||||
static std::function<const char*()> const c_dpadDirections[] = {
|
||||
l_("↑"),
|
||||
l_("→"),
|
||||
l_("↓"),
|
||||
l_("←"),
|
||||
[]() { return "↑"; },
|
||||
[]() { return "→"; },
|
||||
[]() { return "↓"; },
|
||||
[]() { return "←"; },
|
||||
};
|
||||
static std::function<const char*()> const c_controllerTypes[] = {
|
||||
l_("Digital"),
|
||||
|
||||
+5
-6
@@ -215,12 +215,11 @@ void PCSX::Memory::reset() {
|
||||
m_bios[index++] = w & 0xff;
|
||||
w >>= 8;
|
||||
}
|
||||
strcpy((char *)m_bios + index, _(R"(
|
||||
No BIOS loaded, emulation halted.
|
||||
|
||||
Set a BIOS file into the configuration, and do a hard reset of the emulator.
|
||||
The distributed OpenBIOS.bin file can be an appropriate BIOS replacement.
|
||||
)"));
|
||||
std::string nobiosMessage = fmt::format("\n{:19}{}\n\n{}\n", "", _("No BIOS loaded, emulation halted."),
|
||||
_("Set a BIOS file into the configuration, and do a hard reset of the "
|
||||
"emulator.\nThe distributed OpenBIOS.bin file can be an appropriate "
|
||||
"BIOS replacement."));
|
||||
strcpy((char *)m_bios + index, nobiosMessage.c_str());
|
||||
|
||||
uint32_t nobioscrc = crc32(0L, Z_NULL, 0);
|
||||
nobioscrc = crc32(nobioscrc, m_bios, bios_size);
|
||||
|
||||
+54
-21
@@ -119,25 +119,31 @@ bool PCSX::System::loadLocale(const std::string& name, const std::filesystem::pa
|
||||
unsigned inlineIndex = 0;
|
||||
unsigned shift = 0;
|
||||
uint8_t inlined = 0;
|
||||
enum : int {
|
||||
enum {
|
||||
WAITING_MSGIDTOKEN,
|
||||
WAITING_MSGCTXT,
|
||||
WAITING_MSGIDTOKEN_AFTER_CTXT,
|
||||
WAITING_MSGID,
|
||||
WAITING_MSGSTRTOKEN,
|
||||
WAITING_MSGSTR,
|
||||
STATE_MAX
|
||||
} state = WAITING_MSGIDTOKEN;
|
||||
uint64_t hashValue;
|
||||
std::string context;
|
||||
bool hasContext = false;
|
||||
std::map<uint64_t, std::string> locale;
|
||||
|
||||
if (in->failed()) return false;
|
||||
|
||||
std::string comment;
|
||||
// The flags comment comes before the entry it applies to, which is only stored
|
||||
// once the next entry starts, so it is kept per entry.
|
||||
bool fuzzy = false;
|
||||
bool entryFuzzy = false;
|
||||
|
||||
while ((c = in->getc()) >= 0) {
|
||||
if (c == '\n' || c == '\r') {
|
||||
if (inString) return false;
|
||||
if (inComment) fuzzy = comment.find(", fuzzy") != std::string::npos;
|
||||
if (inComment && comment.find(", fuzzy") != std::string::npos) fuzzy = true;
|
||||
inComment = false;
|
||||
newLine = true;
|
||||
comment.clear();
|
||||
@@ -154,7 +160,10 @@ bool PCSX::System::loadLocale(const std::string& name, const std::filesystem::pa
|
||||
continue;
|
||||
}
|
||||
if (c == '\"') {
|
||||
if (state != WAITING_MSGIDTOKEN && state != WAITING_MSGSTRTOKEN) return false;
|
||||
if (state != WAITING_MSGIDTOKEN && state != WAITING_MSGIDTOKEN_AFTER_CTXT &&
|
||||
state != WAITING_MSGSTRTOKEN) {
|
||||
return false;
|
||||
}
|
||||
inString = true;
|
||||
continue;
|
||||
}
|
||||
@@ -229,25 +238,42 @@ bool PCSX::System::loadLocale(const std::string& name, const std::filesystem::pa
|
||||
} else {
|
||||
if (c == ' ' || c == '\t') continue;
|
||||
switch (state) {
|
||||
case WAITING_MSGCTXT:
|
||||
case WAITING_MSGID:
|
||||
case WAITING_MSGSTR:
|
||||
if (c == '\"') {
|
||||
inString = true;
|
||||
(*reinterpret_cast<int*>(&state))++;
|
||||
if (state == STATE_MAX) state = WAITING_MSGIDTOKEN;
|
||||
} else {
|
||||
return false;
|
||||
if (c != '\"') return false;
|
||||
inString = true;
|
||||
switch (state) {
|
||||
case WAITING_MSGCTXT:
|
||||
state = WAITING_MSGIDTOKEN_AFTER_CTXT;
|
||||
break;
|
||||
case WAITING_MSGID:
|
||||
state = WAITING_MSGSTRTOKEN;
|
||||
break;
|
||||
default:
|
||||
state = WAITING_MSGIDTOKEN;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case WAITING_MSGIDTOKEN:
|
||||
case WAITING_MSGIDTOKEN_AFTER_CTXT:
|
||||
case WAITING_MSGSTRTOKEN:
|
||||
if (token.empty()) {
|
||||
switch (state) {
|
||||
case WAITING_MSGIDTOKEN:
|
||||
if (!currentString.empty() && !fuzzy) locale[hashValue] = currentString;
|
||||
if (!currentString.empty() && !entryFuzzy) locale[hashValue] = currentString;
|
||||
entryFuzzy = fuzzy;
|
||||
fuzzy = false;
|
||||
break;
|
||||
case WAITING_MSGSTRTOKEN:
|
||||
hashValue = djb::hash(currentString);
|
||||
case WAITING_MSGIDTOKEN_AFTER_CTXT:
|
||||
context = currentString;
|
||||
hasContext = true;
|
||||
break;
|
||||
default:
|
||||
// A string with a context is looked up as "context\004string",
|
||||
// the same key gettext uses for msgctxt entries.
|
||||
hashValue = djb::hash(hasContext ? context + '\004' + currentString : currentString);
|
||||
hasContext = false;
|
||||
break;
|
||||
}
|
||||
currentString = "";
|
||||
@@ -255,19 +281,26 @@ bool PCSX::System::loadLocale(const std::string& name, const std::filesystem::pa
|
||||
token += c;
|
||||
switch (state) {
|
||||
case WAITING_MSGIDTOKEN:
|
||||
if (token == "msgid") {
|
||||
token = "";
|
||||
state = WAITING_MSGID;
|
||||
} else if (token == "msgctxt") {
|
||||
token = "";
|
||||
state = WAITING_MSGCTXT;
|
||||
} else if (token.length() >= 7) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case WAITING_MSGIDTOKEN_AFTER_CTXT:
|
||||
if (token.length() == 5) {
|
||||
if (token != "msgid") {
|
||||
return false;
|
||||
}
|
||||
if (token != "msgid") return false;
|
||||
token = "";
|
||||
state = WAITING_MSGID;
|
||||
}
|
||||
break;
|
||||
case WAITING_MSGSTRTOKEN:
|
||||
default:
|
||||
if (token.length() == 6) {
|
||||
if (token != "msgstr") {
|
||||
return false;
|
||||
}
|
||||
if (token != "msgstr") return false;
|
||||
token = "";
|
||||
state = WAITING_MSGSTR;
|
||||
}
|
||||
@@ -280,7 +313,7 @@ bool PCSX::System::loadLocale(const std::string& name, const std::filesystem::pa
|
||||
|
||||
if (inString || (state != WAITING_MSGIDTOKEN)) return false;
|
||||
|
||||
if (!currentString.empty() && !fuzzy) locale[hashValue] = currentString;
|
||||
if (!currentString.empty() && !entryFuzzy) locale[hashValue] = currentString;
|
||||
m_locales[name] = locale;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -308,3 +308,8 @@ extern System *g_system;
|
||||
#define f_(str) fmt::runtime(PCSX::g_system->getStr(PCSX::djb::ctHash(str), str))
|
||||
// Lambda string lookup to use with static arrays of strings
|
||||
#define l_(str) []() { return PCSX::g_system->getStr(PCSX::djb::ctHash(str), str); }
|
||||
// Same as _() and l_(), with a translation context for strings whose meaning
|
||||
// depends on where they're used, e.g. C_("Menu", "Update"). The context shows up
|
||||
// as msgctxt in the .pot file, and both arguments need to be string literals.
|
||||
#define C_(ctx, str) PCSX::g_system->getStr(PCSX::djb::ctHash(ctx "\004" str), str)
|
||||
#define lC_(ctx, str) []() { return PCSX::g_system->getStr(PCSX::djb::ctHash(ctx "\004" str), str); }
|
||||
|
||||
+6
-6
@@ -804,7 +804,7 @@ void PCSX::GUI::init(std::function<void()> applyArguments) {
|
||||
m_parallelPortEditor.title = l_("Parallel Port");
|
||||
m_scratchPadEditor.title = l_("Scratch Pad");
|
||||
m_hwrEditor.title = l_("Hardware Registers");
|
||||
m_biosEditor.title = l_("BIOS");
|
||||
m_biosEditor.title = []() { return "BIOS"; };
|
||||
m_vramEditor.title = l_("VRAM");
|
||||
auto makeExportFn = [this](MemoryEditorWrapper& wrapper, std::string postfixName) {
|
||||
return [this, &wrapper, postfixName](size_t len, size_t base_addr) {
|
||||
@@ -1490,7 +1490,7 @@ void PCSX::GUI::endFrame() {
|
||||
ImGui::Separator();
|
||||
if (ImGui::BeginMenu(_("Debug"))) {
|
||||
ImGui::MenuItem(_("Show Logs"), nullptr, &m_log.m_show);
|
||||
if (ImGui::BeginMenu(_("Lua"))) {
|
||||
if (ImGui::BeginMenu("Lua")) {
|
||||
ImGui::MenuItem(_("Show Lua Console"), nullptr, &m_luaConsole.m_show);
|
||||
ImGui::MenuItem(_("Show Lua Inspector"), nullptr, &m_luaInspector.m_show);
|
||||
ImGui::MenuItem(_("Show Lua editor"), nullptr, &m_luaEditor.m_show);
|
||||
@@ -1620,7 +1620,7 @@ in Configuration->Emulation, restart PCSX-Redux, then try again.)"));
|
||||
uint32_t frameCount = g_emulator->m_spu->getFrameCount();
|
||||
ImGui::Text(_("%.2f ms audio buffer (%i frames)"), 1000.0f * frameCount / 44100.0f, frameCount);
|
||||
} else {
|
||||
ImGui::TextUnformatted(_("Idle"));
|
||||
ImGui::TextUnformatted(C_("Audio status", "Idle"));
|
||||
}
|
||||
|
||||
ImGui::EndMainMenuBar();
|
||||
@@ -2010,7 +2010,7 @@ the update and manually apply it.)")));
|
||||
}
|
||||
ImGui::ProgressBar(m_update.progress());
|
||||
if (!m_updateDownloading) {
|
||||
if (ImGui::Button(_("Update"))) {
|
||||
if (ImGui::Button(C_("Update dialog button", "Update"))) {
|
||||
m_updateDownloading = true;
|
||||
bool started = m_update.downloadAndApplyUpdate(
|
||||
g_system->getVersion(),
|
||||
@@ -2033,7 +2033,7 @@ the update and manually apply it.)")));
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Download"))) {
|
||||
if (ImGui::Button(C_("Update dialog button", "Download"))) {
|
||||
m_updateDownloading = true;
|
||||
bool started = m_update.getDownloadUrl(
|
||||
g_system->getVersion(),
|
||||
@@ -2563,7 +2563,7 @@ bool PCSX::GUI::about() {
|
||||
if (version.buildId.has_value()) {
|
||||
ImGui::Text(_("Build: %i"), version.buildId.value());
|
||||
}
|
||||
ImGui::TextUnformatted(_("Changeset: "));
|
||||
ImGui::TextUnformatted(_("Changeset:"));
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SmallButton(version.changeset.c_str())) {
|
||||
openUrl(fmt::format("https://github.com/grumpycoders/pcsx-redux/commit/{}", version.changeset));
|
||||
|
||||
@@ -498,8 +498,8 @@ bool PCSX::Widgets::Assembly::draw(GUI* gui, psxRegisters* registers, Memory* me
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu(_("Debug"))) {
|
||||
if (ImGui::MenuItem(_("Pause"), "F6", nullptr, g_system->running())) g_system->pause();
|
||||
if (ImGui::MenuItem(_("Resume"), "F5", nullptr, !g_system->running())) g_system->resume();
|
||||
if (ImGui::MenuItem(C_("Emulation", "Pause"), "F6", nullptr, g_system->running())) g_system->pause();
|
||||
if (ImGui::MenuItem(C_("Emulation", "Resume"), "F5", nullptr, !g_system->running())) g_system->resume();
|
||||
ImGui::Separator();
|
||||
if (ImGui::MenuItem(_("Step In"), "F11", nullptr, !g_system->running())) g_emulator->m_debug->stepIn();
|
||||
if (ImGui::MenuItem(_("Step Over"), "F10", nullptr, !g_system->running())) g_emulator->m_debug->stepOver();
|
||||
@@ -574,9 +574,9 @@ settings, otherwise debugging features may not work.)");
|
||||
if (ImGui::Button(_("Jump to PC"))) {
|
||||
m_jumpToPC = m_registers->pc;
|
||||
}
|
||||
DButton(_("Pause"), g_system->running(), [&]() mutable { g_system->pause(); });
|
||||
DButton(C_("Emulation", "Pause"), g_system->running(), [&]() mutable { g_system->pause(); });
|
||||
ImGui::SameLine();
|
||||
DButton(_("Resume"), !g_system->running(), [&]() mutable { g_system->resume(); });
|
||||
DButton(C_("Emulation", "Resume"), !g_system->running(), [&]() mutable { g_system->resume(); });
|
||||
ImGui::SameLine();
|
||||
DButton(_("Step In"), !g_system->running(), [&]() mutable { g_emulator->m_debug->stepIn(); });
|
||||
ImGui::SameLine();
|
||||
|
||||
@@ -37,15 +37,15 @@ static uint32_t getValueAboutToWrite(PCSX::R3000Acpu& cpu) {
|
||||
static const char* getBreakpointConditionName(PCSX::Debug::BreakpointCondition condition) {
|
||||
switch (condition) {
|
||||
case PCSX::Debug::BreakpointCondition::Always:
|
||||
return _("Always");
|
||||
return C_("Breakpoint condition", "Always");
|
||||
case PCSX::Debug::BreakpointCondition::Greater:
|
||||
return _("Greater");
|
||||
return C_("Breakpoint condition", "Greater");
|
||||
case PCSX::Debug::BreakpointCondition::Less:
|
||||
return _("Less");
|
||||
return C_("Breakpoint condition", "Less");
|
||||
case PCSX::Debug::BreakpointCondition::Change:
|
||||
return _("Change");
|
||||
return C_("Breakpoint condition", "Change");
|
||||
case PCSX::Debug::BreakpointCondition::Equal:
|
||||
return _("Equal");
|
||||
return C_("Breakpoint condition", "Equal");
|
||||
}
|
||||
return _("Unknown");
|
||||
}
|
||||
@@ -192,9 +192,9 @@ void PCSX::Widgets::Breakpoints::draw(const char* title) {
|
||||
static int range = 8;
|
||||
static int width = 1;
|
||||
if (m_breakpointType != (int)Debug::BreakpointType::Exec) {
|
||||
ImGui::RadioButton(_("Byte"), &width, 1);
|
||||
ImGui::RadioButton(_("Half"), &width, 2);
|
||||
ImGui::RadioButton(_("Word"), &width, 4);
|
||||
ImGui::RadioButton(C_("Memory access width", "Byte"), &width, 1);
|
||||
ImGui::RadioButton(C_("Memory access width", "Half"), &width, 2);
|
||||
ImGui::RadioButton(C_("Memory access width", "Word"), &width, 4);
|
||||
ImGui::RadioButton(_("Range"), &width, 0);
|
||||
|
||||
if (width == 0) {
|
||||
@@ -388,28 +388,38 @@ void PCSX::Widgets::Breakpoints::draw(const char* title) {
|
||||
_("The mapping feature is a simple concept, but requires some amount of explanation. See the documentation "
|
||||
"website for more details, in the Misc Features subsection of the Debugging section."));
|
||||
ImGui::Checkbox(_("Map execution"), &debugger->m_mapping_e);
|
||||
ImGui::Checkbox(_("Map byte reads "), &debugger->m_mapping_r8);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Map half reads "), &debugger->m_mapping_r16);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Map word reads "), &debugger->m_mapping_r32);
|
||||
ImGui::Checkbox(_("Map byte writes "), &debugger->m_mapping_w8);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Map half writes "), &debugger->m_mapping_w16);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Map word writes "), &debugger->m_mapping_w32);
|
||||
if (ImGui::BeginTable("MapFlags", 3, ImGuiTableFlags_SizingFixedFit)) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Map byte reads"), &debugger->m_mapping_r8);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Map half reads"), &debugger->m_mapping_r16);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Map word reads"), &debugger->m_mapping_r32);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Map byte writes"), &debugger->m_mapping_w8);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Map half writes"), &debugger->m_mapping_w16);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Map word writes"), &debugger->m_mapping_w32);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::Separator();
|
||||
ImGui::Checkbox(_("Break on execution map"), &debugger->m_breakmp_e);
|
||||
ImGui::Checkbox(_("Break on byte read map "), &debugger->m_breakmp_r8);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Break on half read map "), &debugger->m_breakmp_r16);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Break on word read map "), &debugger->m_breakmp_r32);
|
||||
ImGui::Checkbox(_("Break on byte write map"), &debugger->m_breakmp_w8);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Break on half write map"), &debugger->m_breakmp_w16);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox(_("Break on word write map"), &debugger->m_breakmp_w32);
|
||||
if (ImGui::BeginTable("BreakFlags", 3, ImGuiTableFlags_SizingFixedFit)) {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Break on byte read map"), &debugger->m_breakmp_r8);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Break on half read map"), &debugger->m_breakmp_r16);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Break on word read map"), &debugger->m_breakmp_r32);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Break on byte write map"), &debugger->m_breakmp_w8);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Break on half write map"), &debugger->m_breakmp_w16);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox(_("Break on word write map"), &debugger->m_breakmp_w32);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
|
||||
@@ -35,12 +35,12 @@ void PCSX::Widgets::Events::draw(IO<File> memFile, const char* title) {
|
||||
ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV;
|
||||
auto events = Kernel::Events::getAllEvents(memFile);
|
||||
if (ImGui::BeginTable("Events", 6, flags)) {
|
||||
ImGui::TableSetupColumn(_("ID"));
|
||||
ImGui::TableSetupColumn("ID");
|
||||
ImGui::TableSetupColumn(_("Core"));
|
||||
ImGui::TableSetupColumn(_("Spec"));
|
||||
ImGui::TableSetupColumn(_("Mode"));
|
||||
ImGui::TableSetupColumn(_("Flag"));
|
||||
ImGui::TableSetupColumn(_("CB"));
|
||||
ImGui::TableSetupColumn("CB");
|
||||
ImGui::TableHeadersRow();
|
||||
for (auto& ev : events) {
|
||||
ImGui::TableNextRow();
|
||||
|
||||
@@ -107,10 +107,10 @@ void PCSX::Widgets::GPUDump::drawPlayer() {
|
||||
if (!player->comment().empty()) ImGui::Text(_("Comment: %s"), player->comment().c_str());
|
||||
ImGui::Text(_("Frame %llu"), static_cast<unsigned long long>(player->frame()));
|
||||
|
||||
if (ImGui::Button(m_playing ? _("Pause") : _("Play"))) m_playing = !m_playing;
|
||||
if (ImGui::Button(m_playing ? C_("Playback", "Pause") : C_("Playback", "Play"))) m_playing = !m_playing;
|
||||
ImGui::SameLine();
|
||||
ImGui::BeginDisabled(m_playing);
|
||||
if (ImGui::Button(_("Step"))) player->step();
|
||||
if (ImGui::Button(C_("Playback", "Step"))) player->step();
|
||||
ImGui::EndDisabled();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Rewind"))) player->rewind();
|
||||
|
||||
@@ -57,8 +57,7 @@ void PCSX::Widgets::GPULogger::draw(PCSX::GPULogger* logger, const char* title)
|
||||
colorFormat == GPU::Logged::DrawLogSettings::ColorFormat::Expanded)) {
|
||||
colorFormat = GPU::Logged::DrawLogSettings::ColorFormat::Expanded;
|
||||
}
|
||||
if (ImGui::MenuItem(_("HTML"), nullptr,
|
||||
colorFormat == GPU::Logged::DrawLogSettings::ColorFormat::HTML)) {
|
||||
if (ImGui::MenuItem("HTML", nullptr, colorFormat == GPU::Logged::DrawLogSettings::ColorFormat::HTML)) {
|
||||
colorFormat = GPU::Logged::DrawLogSettings::ColorFormat::HTML;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
@@ -81,7 +80,7 @@ void PCSX::Widgets::GPULogger::draw(PCSX::GPULogger* logger, const char* title)
|
||||
"and memory."));
|
||||
ImGui::Checkbox(_("Breakpoint on vsync"), &logger->m_breakOnVSync);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button(_("Resume"))) {
|
||||
if (ImGui::Button(C_("Emulation", "Resume"))) {
|
||||
g_system->resume();
|
||||
}
|
||||
ImGui::Checkbox(_("Replay frame"), &m_replay);
|
||||
@@ -245,7 +244,7 @@ void PCSX::Widgets::GPULogger::draw(PCSX::GPULogger* logger, const char* title)
|
||||
break;
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted(_("at PC = "));
|
||||
ImGui::TextUnformatted(_("at PC ="));
|
||||
ImGui::SameLine();
|
||||
label = fmt::format("{:08x}", logged.pc);
|
||||
if (ImGui::Button(label.c_str())) {
|
||||
|
||||
@@ -58,20 +58,20 @@ void PCSX::Widgets::Handlers::draw(const uint32_t* psxMemory, const char* title)
|
||||
}
|
||||
while (infoAddr) {
|
||||
std::string buttonStr;
|
||||
ImGui::TextUnformatted(_("Handler data at "));
|
||||
ImGui::TextUnformatted(_("Handler data at"));
|
||||
ImGui::SameLine();
|
||||
buttonStr = fmt::format("{:08x}##{}", infoAddr, counter++);
|
||||
if (ImGui::Button(buttonStr.c_str())) {
|
||||
g_system->m_eventBus->signal(Events::GUI::JumpToMemory{infoAddr, 16});
|
||||
}
|
||||
ImGui::TextUnformatted(_(" verifier: "));
|
||||
ImGui::Text(" %s", _("verifier:"));
|
||||
ImGui::SameLine();
|
||||
uint32_t verifierAddr = memFile->readAt<uint32_t>(infoAddr + 8);
|
||||
buttonStr = fmt::format("{:08x}##{}", verifierAddr, counter++);
|
||||
if (ImGui::Button(buttonStr.c_str())) {
|
||||
g_system->m_eventBus->signal(Events::GUI::JumpToPC{verifierAddr});
|
||||
}
|
||||
ImGui::TextUnformatted(_(" handler: "));
|
||||
ImGui::Text(" %s", _("handler:"));
|
||||
ImGui::SameLine();
|
||||
uint32_t handlerAddr = memFile->readAt<uint32_t>(infoAddr + 4);
|
||||
buttonStr = fmt::format("{:08x}##{}", handlerAddr, counter++);
|
||||
|
||||
@@ -401,7 +401,7 @@ headers and subheader file boundary markers.)"));
|
||||
ImVec2(0, ImGui::GetContentRegionAvail().y - ImGui::GetFrameHeightWithSpacing() -
|
||||
ImGui::GetStyle().ItemSpacing.y))) {
|
||||
ImGui::TableSetupColumn(_("Path"), ImGuiTableColumnFlags_NoHide);
|
||||
ImGui::TableSetupColumn(_("LBA"), ImGuiTableColumnFlags_WidthFixed, 80.0f);
|
||||
ImGui::TableSetupColumn("LBA", ImGuiTableColumnFlags_WidthFixed, 80.0f);
|
||||
ImGui::TableSetupColumn(_("Size"), ImGuiTableColumnFlags_WidthFixed, 100.0f);
|
||||
ImGui::TableSetupColumn(_("Type"), ImGuiTableColumnFlags_WidthFixed, 60.0f);
|
||||
ImGui::TableHeadersRow();
|
||||
@@ -508,13 +508,13 @@ headers and subheader file boundary markers.)"));
|
||||
typeStr = _("Gap");
|
||||
break;
|
||||
case FlatEntry::HiddenM1:
|
||||
typeStr = _("M1");
|
||||
typeStr = "M1";
|
||||
break;
|
||||
case FlatEntry::HiddenM2F1:
|
||||
typeStr = _("M2F1");
|
||||
typeStr = "M2F1";
|
||||
break;
|
||||
case FlatEntry::HiddenM2F2:
|
||||
typeStr = _("M2F2");
|
||||
typeStr = "M2F2";
|
||||
break;
|
||||
case FlatEntry::System:
|
||||
typeStr = _("System");
|
||||
@@ -618,7 +618,7 @@ significantly by caching the files beforehand.)"));
|
||||
ImGui::TextUnformatted(str.c_str());
|
||||
if (ImGui::BeginTable("Tracks", 5, ImGuiTableFlags_Resizable)) {
|
||||
ImGui::TableSetupColumn(_("Track"));
|
||||
ImGui::TableSetupColumn(_("Start"));
|
||||
ImGui::TableSetupColumn(C_("Track position", "Start"));
|
||||
ImGui::TableSetupColumn(_("Length"));
|
||||
ImGui::TableSetupColumn(_("Pregap"));
|
||||
ImGui::TableSetupColumn("CRC32");
|
||||
@@ -809,7 +809,7 @@ significantly by caching the files beforehand.)"));
|
||||
ImVec2(0, ImGui::GetContentRegionAvail().y - ImGui::GetFrameHeightWithSpacing() -
|
||||
ImGui::GetStyle().ItemSpacing.y))) {
|
||||
ImGui::TableSetupColumn(_("Name"), ImGuiTableColumnFlags_NoHide);
|
||||
ImGui::TableSetupColumn(_("LBA"), ImGuiTableColumnFlags_WidthFixed, 80.0f);
|
||||
ImGui::TableSetupColumn("LBA", ImGuiTableColumnFlags_WidthFixed, 80.0f);
|
||||
ImGui::TableSetupColumn(_("Size"), ImGuiTableColumnFlags_WidthFixed, 100.0f);
|
||||
ImGui::TableHeadersRow();
|
||||
std::unordered_set<uint32_t> visitedDirs;
|
||||
|
||||
@@ -138,7 +138,7 @@ bool PCSX::Widgets::MemcardManager::draw(GUI* gui, const char* title) {
|
||||
g_emulator->m_sio->saveMcd(1);
|
||||
g_emulator->m_sio->saveMcd(2);
|
||||
}
|
||||
ImGui::TextUnformatted(_("Undo version: "));
|
||||
ImGui::TextUnformatted(_("Undo version:"));
|
||||
ImGui::SameLine();
|
||||
if (isLatest) {
|
||||
ImGui::TextUnformatted(_("Latest"));
|
||||
@@ -197,7 +197,7 @@ bool PCSX::Widgets::MemcardManager::draw(GUI* gui, const char* title) {
|
||||
ImGui::TableSetupColumn(_("Block number"));
|
||||
ImGui::TableSetupColumn(_("Icon"));
|
||||
ImGui::TableSetupColumn(_("Title"));
|
||||
ImGui::TableSetupColumn(_("ID"));
|
||||
ImGui::TableSetupColumn("ID");
|
||||
ImGui::TableSetupColumn(_("Filename"));
|
||||
ImGui::TableSetupColumn(_("Action"));
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
@@ -397,7 +397,7 @@ void PCSX::Widgets::MemoryObserver::draw(const char* title) {
|
||||
|
||||
if (ImGui::BeginTabItem(_("Pattern search"))) {
|
||||
if (m_useSIMD) {
|
||||
ImGui::TextUnformatted(_("Sequence size: "));
|
||||
ImGui::TextUnformatted(_("Sequence size:"));
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton(_("8 bytes (fast)"), &m_sequenceSize, 8);
|
||||
ImGui::SameLine();
|
||||
@@ -408,7 +408,7 @@ void PCSX::Widgets::MemoryObserver::draw(const char* title) {
|
||||
|
||||
ImGui::InputText(_("Sequence"), m_sequence, m_sequenceSize + 1);
|
||||
|
||||
ImGui::InputInt(_("Step"), &m_step);
|
||||
ImGui::InputInt(C_("Search increment", "Step"), &m_step);
|
||||
|
||||
if (m_step >= 1 && ImGui::Button(_("Search"))) {
|
||||
if (m_useSIMD && m_sequenceSize == 8) {
|
||||
|
||||
@@ -78,7 +78,7 @@ void PCSX::Widgets::NamedSaveStates::draw(GUI* gui, const char* title) {
|
||||
float posY = ImGui::GetCursorPosY();
|
||||
ImGui::SetCursorPosY(posY + verticalAlignAdjust);
|
||||
|
||||
ImGui::TextUnformatted(_("Filename: "));
|
||||
ImGui::TextUnformatted(_("Filename:"));
|
||||
ImGui::SameLine();
|
||||
ImGui::TextUnformatted(gui->getSaveStatePrefix(true).c_str());
|
||||
ImGui::SameLine(0.0f, 0.0f);
|
||||
|
||||
@@ -85,7 +85,8 @@ void PCSX::Widgets::Patches::draw(const char* title) {
|
||||
ImGui::PopID();
|
||||
|
||||
ImGui::TableSetColumnIndex(3);
|
||||
ImGui::TextUnformatted(patch.type == PCSX::PatchManager::Patch::Type::Return ? _("Return") : _("NOP"));
|
||||
ImGui::TextUnformatted(patch.type == PCSX::PatchManager::Patch::Type::Return ? C_("Patch type", "Return")
|
||||
: "NOP");
|
||||
}
|
||||
ImGui::EndTable();
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ bool PCSX::Widgets::PIOCart::draw(const char* title) {
|
||||
return false;
|
||||
} else {
|
||||
auto pio_rom = settings.get<Emulator::SettingEXP1Filepath>().string();
|
||||
ImGui::InputText(_("ROM"), const_cast<char*>(reinterpret_cast<const char*>(pio_rom.c_str())), pio_rom.length(),
|
||||
ImGui::InputText("ROM", const_cast<char*>(reinterpret_cast<const char*>(pio_rom.c_str())), pio_rom.length(),
|
||||
ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::SameLine();
|
||||
selectEXP1Dialog = ImGui::Button("...");
|
||||
|
||||
@@ -357,7 +357,7 @@ void PCSX::Widgets::TypedDebugger::displayNode(WatchTreeNode* node, const uint32
|
||||
bool addressOfPointer, uint32_t extraImGuiId) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn(); // Name.
|
||||
std::string nameColumnString = fmt::format(f_("{}\t@ {:#x}##{}"), node->name, currentAddress, extraImGuiId);
|
||||
std::string nameColumnString = fmt::format("{}\t@ {:#x}##{}", node->name, currentAddress, extraImGuiId);
|
||||
IO<File> memFile = g_emulator->m_mem->getMemoryAsFile();
|
||||
|
||||
const char* nodeType = node->type.c_str();
|
||||
@@ -560,16 +560,16 @@ void PCSX::Widgets::TypedDebugger::displayNewValueInput(const char* type, size_t
|
||||
case 1:
|
||||
if (equals(type, "char")) {
|
||||
m_newValues[address] = *value.data<int8_t>();
|
||||
if (ImGui::InputScalar(fmt::format(f_("##{}"), address).c_str(), ImGuiDataType_S8,
|
||||
&m_newValues[address], &step, &stepFast, signedFormat, inputFlags)) {
|
||||
if (ImGui::InputScalar(fmt::format("##{}", address).c_str(), ImGuiDataType_S8, &m_newValues[address],
|
||||
&step, &stepFast, signedFormat, inputFlags)) {
|
||||
memFile->write<int8_t>(m_newValues[address]);
|
||||
}
|
||||
} else {
|
||||
// We have a uchar or something of size 1.
|
||||
|
||||
m_newValues[address] = *value.data<uint8_t>();
|
||||
if (ImGui::InputScalar(fmt::format(f_("##{}"), address).c_str(), ImGuiDataType_U8,
|
||||
&m_newValues[address], &step, &stepFast, unsignedFormat, inputFlags)) {
|
||||
if (ImGui::InputScalar(fmt::format("##{}", address).c_str(), ImGuiDataType_U8, &m_newValues[address],
|
||||
&step, &stepFast, unsignedFormat, inputFlags)) {
|
||||
memFile->write<uint8_t>(m_newValues[address]);
|
||||
}
|
||||
}
|
||||
@@ -577,15 +577,15 @@ void PCSX::Widgets::TypedDebugger::displayNewValueInput(const char* type, size_t
|
||||
case 2:
|
||||
if (equals(type, "short")) {
|
||||
m_newValues[address] = *value.data<int16_t>();
|
||||
if (ImGui::InputScalar(fmt::format(f_("##{}"), address).c_str(), ImGuiDataType_S16,
|
||||
&m_newValues[address], &step, &stepFast, signedFormat, inputFlags)) {
|
||||
if (ImGui::InputScalar(fmt::format("##{}", address).c_str(), ImGuiDataType_S16, &m_newValues[address],
|
||||
&step, &stepFast, signedFormat, inputFlags)) {
|
||||
memFile->write<int16_t>(m_newValues[address]);
|
||||
}
|
||||
} else {
|
||||
// We have a ushort or something of size 2.
|
||||
m_newValues[address] = *value.data<uint16_t>();
|
||||
if (ImGui::InputScalar(fmt::format(f_("##{}"), address).c_str(), ImGuiDataType_U16,
|
||||
&m_newValues[address], &step, &stepFast, unsignedFormat, inputFlags)) {
|
||||
if (ImGui::InputScalar(fmt::format("##{}", address).c_str(), ImGuiDataType_U16, &m_newValues[address],
|
||||
&step, &stepFast, unsignedFormat, inputFlags)) {
|
||||
memFile->write<uint16_t>(m_newValues[address]);
|
||||
}
|
||||
}
|
||||
@@ -593,15 +593,15 @@ void PCSX::Widgets::TypedDebugger::displayNewValueInput(const char* type, size_t
|
||||
case 4:
|
||||
if (equals(type, "int") || equals(type, "long")) {
|
||||
m_newValues[address] = *value.data<int32_t>();
|
||||
if (ImGui::InputScalar(fmt::format(f_("##{}"), address).c_str(), ImGuiDataType_S32,
|
||||
&m_newValues[address], &step, &stepFast, signedFormat, inputFlags)) {
|
||||
if (ImGui::InputScalar(fmt::format("##{}", address).c_str(), ImGuiDataType_S32, &m_newValues[address],
|
||||
&step, &stepFast, signedFormat, inputFlags)) {
|
||||
memFile->write<int32_t>(m_newValues[address]);
|
||||
}
|
||||
} else {
|
||||
// We have uint or something of size 4.
|
||||
m_newValues[address] = *value.data<uint32_t>();
|
||||
if (ImGui::InputScalar(fmt::format(f_("##{}"), address).c_str(), ImGuiDataType_U32,
|
||||
&m_newValues[address], &step, &stepFast, unsignedFormat, inputFlags)) {
|
||||
if (ImGui::InputScalar(fmt::format("##{}", address).c_str(), ImGuiDataType_U32, &m_newValues[address],
|
||||
&step, &stepFast, unsignedFormat, inputFlags)) {
|
||||
memFile->write<uint32_t>(m_newValues[address]);
|
||||
}
|
||||
}
|
||||
@@ -781,7 +781,7 @@ Arrays and pointers are specified as for data types)"));
|
||||
ImGui::SameLine();
|
||||
if (numberToCreate > 0 && ImGui::Button("Add") && m_structs.contains(type)) {
|
||||
WatchTreeNode rootNode;
|
||||
const auto inputType = createArray ? fmt::format(f_("{}[{}]"), type, numberToCreate) : type;
|
||||
const auto inputType = createArray ? fmt::format("{}[{}]", type, numberToCreate) : type;
|
||||
rootNode.type = inputType;
|
||||
rootNode.name = inputType;
|
||||
for (const auto& field : m_structs[type]) {
|
||||
@@ -823,7 +823,7 @@ Arrays and pointers are specified as for data types)"));
|
||||
ImGui::Checkbox("Input in hexadecimal", &m_hex);
|
||||
|
||||
gui->useMonoFont();
|
||||
if (ImGui::BeginTable(_("WatchTable"), 6, treeTableFlags)) {
|
||||
if (ImGui::BeginTable("WatchTable", 6, treeTableFlags)) {
|
||||
ImGui::TableSetupColumn(_("Name"));
|
||||
ImGui::TableSetupColumn(_("Type"));
|
||||
ImGui::TableSetupColumn(_("Size"));
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ XA audio and audio tracks.)"));
|
||||
_("Cubic interpolation - better treble")};
|
||||
changed |= ImGui::Combo(_("Interpolation"), &settings.get<Interpolation>().value, interpolationValues,
|
||||
IM_ARRAYSIZE(interpolationValues));
|
||||
changed |= ImGui::Checkbox(_("Mono"), &settings.get<Mono>().value);
|
||||
changed |= ImGui::Checkbox(C_("Audio channels", "Mono"), &settings.get<Mono>().value);
|
||||
ImGuiHelpers::ShowHelpMarker(_("Downmixes stereo to mono."));
|
||||
changed |= ImGui::InputInt(_("Speed multiplier"), &settings.get<Speed>().value);
|
||||
ImGuiHelpers::ShowHelpMarker(_(R"(Emulation speed, applied at the audio sink (the master clock).
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2026 PCSX-Redux authors *
|
||||
* *
|
||||
* This program 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program 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 this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "core/system.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class TestSystem final : public PCSX::System {
|
||||
public:
|
||||
void softReset() override {}
|
||||
void hardReset() override {}
|
||||
void biosPutc(int) override {}
|
||||
const PCSX::Arguments& getArgs() const override { throw std::logic_error("unused"); }
|
||||
void printf(std::string&&) override {}
|
||||
void log(PCSX::LogClass, std::string&&) override {}
|
||||
void message(std::string&&) override {}
|
||||
void luaMessage(const std::string&, bool) override {}
|
||||
void update(bool) override {}
|
||||
void close() override {}
|
||||
void purgeAllEvents() override {}
|
||||
void testQuit(int) override {}
|
||||
};
|
||||
|
||||
const char* const c_poFile = R"(msgid ""
|
||||
msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
|
||||
#: src/a.cc:1
|
||||
msgid "Mono"
|
||||
msgstr "Mono-fr"
|
||||
|
||||
#: src/b.cc:1
|
||||
msgctxt "Audio channels"
|
||||
msgid "Mono"
|
||||
msgstr "Mono-audio"
|
||||
|
||||
msgctxt ""
|
||||
"Multi"
|
||||
"line"
|
||||
msgid ""
|
||||
"Split "
|
||||
"string"
|
||||
msgstr "Split-ctx"
|
||||
|
||||
#, fuzzy
|
||||
msgctxt "Playback"
|
||||
msgid "Pause"
|
||||
msgstr "Pause-fuzzy"
|
||||
|
||||
msgid "Last"
|
||||
msgstr "Last-fr"
|
||||
)";
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(I18n, Context) {
|
||||
auto path = std::filesystem::temp_directory_path() / "pcsx-redux-i18n-test.po";
|
||||
{
|
||||
std::ofstream out(path, std::ios::binary);
|
||||
out << c_poFile;
|
||||
}
|
||||
TestSystem system;
|
||||
ASSERT_TRUE(system.loadLocale("Test", path));
|
||||
system.activateLocale("Test");
|
||||
auto* oldSystem = PCSX::g_system;
|
||||
PCSX::g_system = &system;
|
||||
EXPECT_STREQ(_("Mono"), "Mono-fr");
|
||||
EXPECT_STREQ(C_("Audio channels", "Mono"), "Mono-audio");
|
||||
EXPECT_STREQ(C_("Multiline", "Split string"), "Split-ctx");
|
||||
EXPECT_STREQ(C_("Playback", "Pause"), "Pause");
|
||||
EXPECT_STREQ(C_("Other", "Mono"), "Mono");
|
||||
EXPECT_STREQ(lC_("Audio channels", "Mono")(), "Mono-audio");
|
||||
EXPECT_STREQ(_("Last"), "Last-fr");
|
||||
PCSX::g_system = oldSystem;
|
||||
std::filesystem::remove(path);
|
||||
}
|
||||
Reference in New Issue
Block a user