Starting i18n stub.

This commit is contained in:
Nicolas "Pixel" Noble 2019-05-21 21:19:46 +02:00 committed by Nicolas Pixel Noble
parent cbc999183b
commit b600eb4835
12 changed files with 754 additions and 6 deletions

2
.gitattributes vendored
View file

@ -2,3 +2,5 @@
*.vcxproj text
*.sln text
*.po text
*.pot text

View file

@ -3,6 +3,8 @@ TARGET := pcsx-redux
PACKAGES := libavcodec libavformat libavutil libswresample sdl2 zlib
LOCALES := fr
CXXFLAGS := -std=c++2a
CPPFLAGS := `pkg-config --cflags $(PACKAGES)`
CPPFLAGS += -Isrc
@ -62,14 +64,28 @@ gitclean:
git clean -f -d -x
git submodule foreach --recursive git clean -f -d -x
define msgmerge
msgmerge --update i18n/$(1).po i18n/pcsx-redux.pot
endef
regen-i18n:
find src -name *.cc -or -name *.c -or -name *.h > pcsx-src-list.txt
xgettext --keyword=_ --language=C++ --add-comments --sort-output -o i18n/pcsx-redux.pot --omit-header --join-existing -f pcsx-src-list.txt
rm pcsx-src-list.txt
$(foreach l,$(LOCALES),$(call msgmerge,$(l)))
.PHONY: all clean gitclean regen-i18n
DEPS := $(patsubst %.cc,%.dep,$(SRC_CC))
DEPS += $(patsubst %.cpp,%.dep,$(SRC_CPP))
DEPS += $(patsubst %.c,%.dep,$(SRC_C))
dep: $(DEPS)
ifneq ($(MAKECMDGOALS), regen-i18n)
ifneq ($(MAKECMDGOALS), clean)
ifneq ($(MAKECMDGOALS), gitclean)
-include $(DEPS)
endif
endif
endif

269
i18n/fr.po Normal file
View file

@ -0,0 +1,269 @@
msgid ""
msgstr ""
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: src/core/cdriso.cc:1686
#, c-format
msgid ""
"\n"
"Detected ECM file with proper header and filename suffix.\n"
msgstr ""
#: src/core/cdriso.cc:810
#, c-format
msgid ""
"\n"
"could not open: %s\n"
msgstr ""
#: src/core/cheat.cc:288 src/core/cheat.cc:403
msgid "(Untitled)"
msgstr ""
#: src/core/cdriso.cc:530
#, c-format
msgid "Actual %i vs. %i estimated\n"
msgstr ""
#: src/core/cdriso.cc:529
#, c-format
msgid "Buffer overflow..."
msgstr ""
#: src/core/misc.cc:382
#, c-format
msgid "CD-ROM EXE Name: %.255s\n"
msgstr ""
#: src/core/misc.cc:381
#, c-format
msgid "CD-ROM ID: %.9s\n"
msgstr ""
#: src/core/misc.cc:380
#, c-format
msgid "CD-ROM Label: %.32s\n"
msgstr ""
#: src/core/cheat.cc:126
#, c-format
msgid "Cheats loaded from: %s\n"
msgstr ""
#: src/core/cheat.cc:157
#, c-format
msgid "Cheats saved to: %s\n"
msgstr ""
#. ClosePlugins();
#: src/core/sio.cc:740
msgid "Connection closed!\n"
msgstr ""
#: src/core/cdriso.cc:437
#, c-format
msgid "Could not allocate audio codec for the input, aborting\n"
msgstr ""
#: src/core/cdriso.cc:463
#, c-format
msgid "Could not allocate frame\n"
msgstr ""
#: src/core/cdriso.cc:511
#, c-format
msgid "Could not allocate memory to decode CDDA TRACK: %s\n"
msgstr ""
#: src/core/cdriso.cc:445
#, c-format
msgid "Could not allocate resample context"
msgstr ""
#: src/core/cdriso.cc:363
#, c-format
msgid "Could not find %s stream in input file\n"
msgstr ""
#: src/core/cdriso.cc:429
#, c-format
msgid "Could not find audio codec for the input, aborting\n"
msgstr ""
#: src/core/cdriso.cc:421
#, c-format
msgid "Could not find audio stream in the input, aborting\n"
msgstr ""
#: src/core/cdriso.cc:411
#, c-format
msgid "Could not find stream information\n"
msgstr ""
#: src/core/cheat.cc:54
#, c-format
msgid "Could not load cheats from: %s\n"
msgstr ""
#: src/core/psxmem.cc:85
#, c-format
msgid "Could not open BIOS:\"%s\". Enabling HLE Bios!\n"
msgstr ""
#: src/core/cdriso.cc:456
#, c-format
msgid "Could not open resample context"
msgstr ""
#: src/core/cdriso.cc:406
#, c-format
msgid "Could not open source file %s\n"
msgstr ""
#: src/core/cdriso.cc:523
#, c-format
msgid "Decoding audio tr#%u (%s)..."
msgstr ""
#: src/core/psxmem.cc:42
msgid "Error allocating memory!"
msgstr ""
#: src/core/cdriso.cc:333
#, c-format
msgid "Error decoding audio frame\n"
msgstr ""
#: src/core/plugins.cc:696
#, c-format
msgid "Error initializing GPU plugin: %d"
msgstr ""
#: src/core/plugins.cc:708
#, c-format
msgid "Error initializing NetPlay plugin: %d"
msgstr ""
#: src/core/plugins.cc:716
#, c-format
msgid "Error initializing SIO1 plugin: %d"
msgstr ""
#: src/core/plugins.cc:701
#, c-format
msgid "Error initializing SPU plugin: %d"
msgstr ""
#: src/core/plugins.cc:230
#, c-format
msgid "Error loading %s: %s"
msgstr ""
#: src/core/misc.cc:462 src/core/misc.cc:586
#, c-format
msgid "Error opening file: %s.\n"
msgstr ""
#: src/core/cdriso.cc:371 src/core/cdriso.cc:377
#, c-format
msgid "Failed to find %s codec\n"
msgstr ""
#: src/core/cdriso.cc:384
#, c-format
msgid "Failed to open %s codec\n"
msgstr ""
#: src/core/ppf.cc:212
#, c-format
msgid "Invalid PPF patch: %s.\n"
msgstr ""
#: src/core/psxmem.cc:90
#, c-format
msgid "Loaded BIOS: %s\n"
msgstr ""
#: src/core/cdriso.cc:1895
#, c-format
msgid "Loaded CD Image: %s"
msgstr ""
#. build address array
#: src/core/ppf.cc:327
#, c-format
msgid "Loaded PPF %d.0 patch: %s.\n"
msgstr ""
#: src/core/cdriso.cc:1319
#, c-format
msgid "Loaded SBI file: %s.\n"
msgstr ""
#: src/core/sio.cc:800
#, c-format
msgid "Loading memory card %s\n"
msgstr ""
#: src/core/sio.cc:797
#, c-format
msgid "Memory card %s failed to load!\n"
msgstr ""
#: src/core/sio.cc:772
#, c-format
msgid "No memory card value was specified - card %i is not plugged.\n"
msgstr ""
#. change handle to decoded one
#: src/core/cdriso.cc:535
#, c-format
msgid "OK\n"
msgstr ""
#: src/core/plugins.cc:721
msgid "Plugins loaded.\n"
msgstr ""
#: src/core/sio.cc:839
#, c-format
msgid "Saving memory card %s\n"
msgstr ""
#: src/core/sio.cc:782
#, c-format
msgid "The memory card %s doesn't exist - creating it\n"
msgstr ""
#: src/core/misc.cc:536
msgid "This file does not appear to be a valid PSX file.\n"
msgstr ""
#: src/core/cdriso.cc:1874
#, c-format
msgid "Track %.2d (%s) - Start %.2d:%.2d:%.2d, Length %.2d:%.2d:%.2d\n"
msgstr ""
#: src/core/misc.cc:505
#, c-format
msgid "Unknown CPE opcode %02x at position %08x.\n"
msgstr ""
#: src/core/ppf.cc:288
#, c-format
msgid "Unsupported PPF version (%d).\n"
msgstr ""
#: src/core/misc.cc:573
#, c-format
msgid "ng Load Bin file: [0x%08x] : %s\n"
msgstr ""
#: src/core/misc.cc:575
#, c-format
msgid "ok Load Bin file: [0x%08x] : %s\n"
msgstr ""

261
i18n/pcsx-redux.pot Normal file
View file

@ -0,0 +1,261 @@
#: src/core/cdriso.cc:1686
#, c-format
msgid ""
"\n"
"Detected ECM file with proper header and filename suffix.\n"
msgstr ""
#: src/core/cdriso.cc:810
#, c-format
msgid ""
"\n"
"could not open: %s\n"
msgstr ""
#: src/core/cheat.cc:288 src/core/cheat.cc:403
msgid "(Untitled)"
msgstr ""
#: src/core/cdriso.cc:530
#, c-format
msgid "Actual %i vs. %i estimated\n"
msgstr ""
#: src/core/cdriso.cc:529
#, c-format
msgid "Buffer overflow..."
msgstr ""
#: src/core/misc.cc:382
#, c-format
msgid "CD-ROM EXE Name: %.255s\n"
msgstr ""
#: src/core/misc.cc:381
#, c-format
msgid "CD-ROM ID: %.9s\n"
msgstr ""
#: src/core/misc.cc:380
#, c-format
msgid "CD-ROM Label: %.32s\n"
msgstr ""
#: src/core/cheat.cc:126
#, c-format
msgid "Cheats loaded from: %s\n"
msgstr ""
#: src/core/cheat.cc:157
#, c-format
msgid "Cheats saved to: %s\n"
msgstr ""
#. ClosePlugins();
#: src/core/sio.cc:740
msgid "Connection closed!\n"
msgstr ""
#: src/core/cdriso.cc:437
#, c-format
msgid "Could not allocate audio codec for the input, aborting\n"
msgstr ""
#: src/core/cdriso.cc:463
#, c-format
msgid "Could not allocate frame\n"
msgstr ""
#: src/core/cdriso.cc:511
#, c-format
msgid "Could not allocate memory to decode CDDA TRACK: %s\n"
msgstr ""
#: src/core/cdriso.cc:445
#, c-format
msgid "Could not allocate resample context"
msgstr ""
#: src/core/cdriso.cc:363
#, c-format
msgid "Could not find %s stream in input file\n"
msgstr ""
#: src/core/cdriso.cc:429
#, c-format
msgid "Could not find audio codec for the input, aborting\n"
msgstr ""
#: src/core/cdriso.cc:421
#, c-format
msgid "Could not find audio stream in the input, aborting\n"
msgstr ""
#: src/core/cdriso.cc:411
#, c-format
msgid "Could not find stream information\n"
msgstr ""
#: src/core/cheat.cc:54
#, c-format
msgid "Could not load cheats from: %s\n"
msgstr ""
#: src/core/psxmem.cc:85
#, c-format
msgid "Could not open BIOS:\"%s\". Enabling HLE Bios!\n"
msgstr ""
#: src/core/cdriso.cc:456
#, c-format
msgid "Could not open resample context"
msgstr ""
#: src/core/cdriso.cc:406
#, c-format
msgid "Could not open source file %s\n"
msgstr ""
#: src/core/cdriso.cc:523
#, c-format
msgid "Decoding audio tr#%u (%s)..."
msgstr ""
#: src/core/psxmem.cc:42
msgid "Error allocating memory!"
msgstr ""
#: src/core/cdriso.cc:333
#, c-format
msgid "Error decoding audio frame\n"
msgstr ""
#: src/core/plugins.cc:696
#, c-format
msgid "Error initializing GPU plugin: %d"
msgstr ""
#: src/core/plugins.cc:708
#, c-format
msgid "Error initializing NetPlay plugin: %d"
msgstr ""
#: src/core/plugins.cc:716
#, c-format
msgid "Error initializing SIO1 plugin: %d"
msgstr ""
#: src/core/plugins.cc:701
#, c-format
msgid "Error initializing SPU plugin: %d"
msgstr ""
#: src/core/plugins.cc:230
#, c-format
msgid "Error loading %s: %s"
msgstr ""
#: src/core/misc.cc:462 src/core/misc.cc:586
#, c-format
msgid "Error opening file: %s.\n"
msgstr ""
#: src/core/cdriso.cc:371 src/core/cdriso.cc:377
#, c-format
msgid "Failed to find %s codec\n"
msgstr ""
#: src/core/cdriso.cc:384
#, c-format
msgid "Failed to open %s codec\n"
msgstr ""
#: src/core/ppf.cc:212
#, c-format
msgid "Invalid PPF patch: %s.\n"
msgstr ""
#: src/core/psxmem.cc:90
#, c-format
msgid "Loaded BIOS: %s\n"
msgstr ""
#: src/core/cdriso.cc:1895
#, c-format
msgid "Loaded CD Image: %s"
msgstr ""
#. build address array
#: src/core/ppf.cc:327
#, c-format
msgid "Loaded PPF %d.0 patch: %s.\n"
msgstr ""
#: src/core/cdriso.cc:1319
#, c-format
msgid "Loaded SBI file: %s.\n"
msgstr ""
#: src/core/sio.cc:800
#, c-format
msgid "Loading memory card %s\n"
msgstr ""
#: src/core/sio.cc:797
#, c-format
msgid "Memory card %s failed to load!\n"
msgstr ""
#: src/core/sio.cc:772
#, c-format
msgid "No memory card value was specified - card %i is not plugged.\n"
msgstr ""
#. change handle to decoded one
#: src/core/cdriso.cc:535
#, c-format
msgid "OK\n"
msgstr ""
#: src/core/plugins.cc:721
msgid "Plugins loaded.\n"
msgstr ""
#: src/core/sio.cc:839
#, c-format
msgid "Saving memory card %s\n"
msgstr ""
#: src/core/sio.cc:782
#, c-format
msgid "The memory card %s doesn't exist - creating it\n"
msgstr ""
#: src/core/misc.cc:536
msgid "This file does not appear to be a valid PSX file.\n"
msgstr ""
#: src/core/cdriso.cc:1874
#, c-format
msgid "Track %.2d (%s) - Start %.2d:%.2d:%.2d, Length %.2d:%.2d:%.2d\n"
msgstr ""
#: src/core/misc.cc:505
#, c-format
msgid "Unknown CPE opcode %02x at position %08x.\n"
msgstr ""
#: src/core/ppf.cc:288
#, c-format
msgid "Unsupported PPF version (%d).\n"
msgstr ""
#: src/core/misc.cc:573
#, c-format
msgid "ng Load Bin file: [0x%08x] : %s\n"
msgstr ""
#: src/core/misc.cc:575
#, c-format
msgid "ok Load Bin file: [0x%08x] : %s\n"
msgstr ""

View file

@ -103,6 +103,17 @@ char *PCSX::File::gets(char *s, int size) {
size--;
}
}
std::string PCSX::File::gets() {
int c;
std::string ret;
while (true) {
c = getc();
if ((c == 0) || (c == -1)) {
return ret;
}
ret += c;
}
}
ssize_t PCSX::File::read(void *dest, ssize_t size) {
if (m_handle) return fread(dest, 1, size, m_handle);
if (!m_data) return -1;

View file

@ -41,6 +41,7 @@ class File {
~File() { close(); }
File* dup() { return new File(m_filename); }
char* gets(char* s, int size);
std::string gets();
ssize_t read(void* dest, ssize_t size);
ssize_t write(const void* dest, size_t size);
int getc();

View file

@ -78,9 +78,6 @@
typedef intptr_t ssize_t;
#endif
#define _(msgid) msgid
#define N_(msgid) msgid
namespace PCSX {
class Bios;
@ -133,9 +130,10 @@ class Emulator {
typedef Setting<bool, irqus::typestring<'V', 'e', 'r', 'b', 'o', 's', 'e'>> SettingVerbose;
typedef Setting<bool, irqus::typestring<'R', 'C', 'n', 't', 'F', 'i', 'x'>> SettingRCntFix;
typedef SettingPath<irqus::typestring<'I', 's', 'o', 'P', 'a', 't', 'h'>> SettingIsoPath;
typedef SettingString<irqus::typestring<'L', 'o', 'c', 'a', 'l', 'e'>> SettingLocale;
Settings<SettingStdout, SettingLogfile, SettingMcd1, SettingMcd2, SettingBios, SettingPpfDir, SettingPsxExe,
SettingXa, SettingSioIrq, SettingSpuIrq, SettingBnWMdec, SettingAutoVideo, SettingVideo, SettingCDDA,
SettingHLE, SettingFastBoot, SettingDebug, SettingVerbose, SettingRCntFix, SettingIsoPath>
SettingHLE, SettingFastBoot, SettingDebug, SettingVerbose, SettingRCntFix, SettingIsoPath, SettingLocale>
settings;
class PcsxConfig {
public:

View file

@ -19,6 +19,117 @@
#include <stddef.h>
#include <iomanip>
#include <sstream>
#include "core/file.h"
#include "core/system.h"
PCSX::System* PCSX::g_system = NULL;
bool PCSX::System::loadLocale(const std::string & name, const std::filesystem::path & path) {
std::unique_ptr<File> in(new File(path));
int c;
std::stringstream ss;
std::string currentString = "";
std::string token = "";
std::string singleChar = ".";
bool newLine = true;
bool inComment = false;
bool inString = false;
bool gotBackquote = false;
enum : int {
WAITING_MSGIDTOKEN,
WAITING_MSGID,
WAITING_MSGSTRTOKEN,
WAITING_MSGSTR,
STATE_MAX
} state = WAITING_MSGIDTOKEN;
uint64_t hashValue;
std::map<uint64_t, std::string> locale;
while ((c = in->getc()) >= 0) {
if (c == '\n') {
inComment = false;
newLine = true;
continue;
}
if (inComment) continue;
if (newLine) {
newLine = false;
if (c == '#') {
inComment = true;
continue;
}
if (c == '\"') {
if (state != WAITING_MSGIDTOKEN && state != WAITING_MSGSTRTOKEN) return false;
ss << "\"";
inString = true;
continue;
}
}
if (inString) {
singleChar[0] = c;
ss << singleChar;
if (c == '\"' && !gotBackquote) {
std::string quotedString;
ss >> std::quoted(quotedString);
currentString += quotedString;
inString = false;
}
gotBackquote = c == '\\';
} else {
if (c == ' ' || c == '\t') continue;
switch (state) {
case WAITING_MSGID:
case WAITING_MSGSTR:
if (c == '\"') {
ss << "\"";
inString = true;
(*reinterpret_cast<int*>(&state))++;
if (state == STATE_MAX) state = WAITING_MSGIDTOKEN;
} else {
return false;
}
break;
case WAITING_MSGIDTOKEN:
case WAITING_MSGSTRTOKEN:
if (token.length() == 0) {
switch (state) {
case WAITING_MSGIDTOKEN:
if (currentString.length()) locale[hashValue] = currentString;
break;
case WAITING_MSGSTRTOKEN:
hashValue = hash(currentString);
break;
}
currentString = "";
}
token += c;
switch (state) {
case WAITING_MSGIDTOKEN:
if (token.length() == 5) {
if (token != "msgid") return false;
token = "";
state = WAITING_MSGID;
}
break;
case WAITING_MSGSTRTOKEN:
if (token.length() == 6) {
if (token != "msgstr") return false;
token = "";
state = WAITING_MSGSTR;
}
break;
}
break;
}
}
}
if (inString || (state != WAITING_MSGIDTOKEN)) return false;
if (currentString != "") locale[hashValue] = currentString;
m_locales[name] = locale;
return true;
}

View file

@ -22,6 +22,9 @@
#include <stdarg.h>
#include <filesystem>
#include <map>
namespace PCSX {
class System {
@ -58,6 +61,44 @@ class System {
}
private:
static inline constexpr uint64_t djbProcess(uint64_t hash, const char str[], size_t n) {
return n ? djbProcess(((hash << 5) + hash) ^ str[0], str + 1, n - 1) : hash;
}
public:
template <size_t S>
static inline constexpr uint64_t ctHash(const char (&str)[S]) {
return djbProcess(5381, str, S - 1);
}
static inline constexpr uint64_t hash(const char *str, size_t n) { return djbProcess(5381, str, n); }
static inline uint64_t hash(const std::string &str) { return djbProcess(5381, str.c_str(), str.length()); }
const char *getStr(uint64_t hash, const char *str) {
auto ret = m_i18n.find(hash);
if (ret == m_i18n.end()) return str;
return ret->second.c_str();
}
bool loadLocale(const std::string &name, const std::filesystem::path &path);
void activateLocale(const std::string &name) {
auto locale = m_locales.find(name);
if (locale == m_locales.end()) return;
m_i18n = locale->second;
m_currentLocale = name;
}
std::string localeName() { return m_currentLocale; }
std::vector<std::string> localesNames() {
std::vector<std::string> locales;
for (auto &l : m_locales) {
locales.push_back(l.first);
}
return locales;
}
private:
std::map<uint64_t, std::string> m_i18n;
std::map<std::string, decltype(m_i18n)> m_locales;
std::string m_currentLocale;
bool m_running = false;
bool m_quitting = false;
};
@ -65,3 +106,5 @@ class System {
extern System *g_system;
} // namespace PCSX
#define _(str) PCSX::g_system->getStr(PCSX::System::ctHash(str), str)

View file

@ -496,7 +496,7 @@ void PCSX::GUI::endFrame() {
if (m_breakpoints.m_show) {
m_breakpoints.draw("Breakpoints");
}
about();
biosCounters();
@ -535,6 +535,26 @@ bool PCSX::GUI::configure() {
ImGui::SetNextWindowPos(ImVec2(50, 30), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(300, 500), ImGuiCond_FirstUseEver);
if (ImGui::Begin("Emulation Configuration", &m_showCfg)) {
{
std::string currentLocale = g_system->localeName();
if (currentLocale.length() == 0) currentLocale = "English";
if (ImGui::BeginCombo(_("Locale"), currentLocale.c_str())) {
if (ImGui::Selectable("English", currentLocale == "English")) {
g_system->activateLocale("English");
g_emulator.settings.get<Emulator::SettingLocale>() = "English";
changed = true;
}
for (auto& l : g_system->localesNames()) {
if (ImGui::Selectable(l.c_str(), currentLocale == l)) {
g_system->activateLocale(l);
g_emulator.settings.get<Emulator::SettingLocale>() = l;
changed = true;
}
}
ImGui::EndCombo();
}
}
ImGui::Separator();
changed |= ImGui::Checkbox("Enable XA decoder", &settings.get<Emulator::SettingXa>().value);
changed |= ImGui::Checkbox("Always enable SIO IRQ", &settings.get<Emulator::SettingSioIrq>().value);
changed |= ImGui::Checkbox("Always enable SPU IRQ", &settings.get<Emulator::SettingSpuIrq>().value);
@ -693,7 +713,7 @@ void PCSX::GUI::about() {
ImGui::SetNextWindowPos(ImVec2(200, 100), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(880, 600), ImGuiCond_FirstUseEver);
if (ImGui::Begin("About", &m_showAbout)) {
ImGui::Text("PCSX-Redux", &m_showAbout);
ImGui::Text("PCSX-Redux");
ImGui::Separator();
auto someString = [](const char* str, GLenum index) {
const char* value = (const char*)glGetString(index);

View file

@ -19,6 +19,10 @@
#include <SDL.h>
#include <filesystem>
#include <map>
#include <string>
#include "core/cdrom.h"
#include "core/gpu.h"
#include "core/psxemulator.h"
@ -175,6 +179,13 @@ int main(int argc, char **argv) {
const auto &logfile = PCSX::g_emulator.settings.get<PCSX::Emulator::SettingLogfile>().string();
if (!logfile.empty()) system->useLogfile(logfile);
std::filesystem::path self = argv[0];
std::filesystem::path binDir = self.parent_path();
static const std::map<std::string, std::string> locales = {{"Français", "fr.po"}};
for (auto &l : locales) system->loadLocale(l.first, binDir / l.second);
system->activateLocale(PCSX::g_emulator.settings.get<PCSX::Emulator::SettingLocale>());
LoadPlugins();
PCSX::g_emulator.m_gpu->open(s_gui);
PCSX::g_emulator.m_spu->open();

View file

@ -24,3 +24,8 @@ find repository/vsprojects -name *.vcxproj | while read f ; do
echo "$f"
clean "$f"
done
find repository/i18n -type f | while read f ; do
echo "$f"
clean "$f"
done