Add translations (#153)

* Add translations from v1

* Add font configuration (to be able to use non-latin languages)

* translations: remove includes that are already in pch.h

* translations: rename enums and avoid macros

* Fix crash when the font file doesn't exist

* translations: avoid u8 to avoid reencoding by MSVC

MSVC will read the file as ASCII and reconvert characters as UTF-8, this will corrupt characters as the file is in fact already in UTF-8.

* translations: remove NUMBER in enums

* translations: handle non existing translations gracefuly (don't crash)

Fallback to english if available, else return empty string

* Testing pull collaboration.

* Rollback: remove NUMBER in enums.

* Get rid of namespace, use header instead.

* Collapsed translated text struct and array.

* Fixed build errors and warnings.

* Simplified language list.

* All new types, locals and globals should use CamelCase.

* Removed unnecessary ImGui patch.

* Rearranged TTextBox immediate mode draw.

* Final touches: removed unused declaration in gdrv.
Removed unused Msg entries and added new check.

* Remove placeholder english texts from missing translations

Co-authored-by: Muzychenko Andrey <33288308+k4zmu2a@users.noreply.github.com>
This commit is contained in:
Alexis MurzeauandMuzychenko Andrey authored and GitHub committed 2022-08-31 07:58:03 +03:00
1 parent c1c74878df
commit 66a868083a
22 files changed
+7957 -461

No files matched your search

+91 -29
View File
@@ -9,6 +9,8 @@
#include "pb.h"
#include "render.h"
#include "Sound.h"
#include "translations.h"
#include "font_selection.h"
SDL_Window* winmain::MainWindow = nullptr;
SDL_Renderer* winmain::Renderer = nullptr;
@@ -64,7 +66,7 @@ int winmain::WinMain(LPCSTR lpCmdLine)
// SDL window
SDL_Window* window = SDL_CreateWindow
(
pinball::get_rc_string(38, 0),
pinball::get_rc_string(Msg::STRING139),
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
800, 556,
SDL_WINDOW_HIDDEN | SDL_WINDOW_RESIZABLE
@@ -106,9 +108,6 @@ int winmain::WinMain(LPCSTR lpCmdLine)
ImGui::StyleColorsDark();
ImGuiIO& io = ImGui::GetIO();
ImIO = &io;
// ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
auto prefPath = SDL_GetPrefPath(nullptr, "SpaceCadetPinball");
auto iniPath = std::string(prefPath) + "imgui_pb.ini";
@@ -117,6 +116,40 @@ int winmain::WinMain(LPCSTR lpCmdLine)
// First step: just load the options
options::InitPrimary();
if(!Options.FontFileName.empty())
{
ImGuiSDL::Deinitialize();
io.Fonts->Clear();
ImVector<ImWchar> ranges;
translations::GetGlyphRange(&ranges);
ImFontConfig fontConfig{};
// ToDo: further tweak font options, maybe try imgui_freetype
fontConfig.OversampleV = 2;
fontConfig.OversampleH = 4;
// ToDo: improve font file test, checking if file exists is not enough
auto fileName = Options.FontFileName.c_str();
auto fileHandle = fopenu(fileName, "rb");
if (fileHandle)
{
fclose(fileHandle);
// ToDo: Bind font size to UI scale
if (!io.Fonts->AddFontFromFileTTF(fileName, 13.f, &fontConfig, ranges.Data))
io.Fonts->AddFontDefault();
}
else
io.Fonts->AddFontDefault();
io.Fonts->Build();
ImGuiSDL::Initialize(renderer, 0, 0);
}
// ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad;
// Data search order: WD, executable path, user pref path, platform specific paths.
auto basePath = SDL_GetBasePath();
std::vector<const char*> searchPaths
@@ -372,34 +405,34 @@ void winmain::RenderUi()
fullscrn::window_size_changed();
}
if (ImGui::BeginMenu("Game"))
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Game)))
{
if (ImGui::MenuItem("New Game", "F2"))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_New_Game), "F2"))
{
new_game();
}
if (ImGui::MenuItem("Launch Ball", nullptr, false, LaunchBallEnabled))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Launch_Ball), nullptr, false, LaunchBallEnabled))
{
end_pause();
pb::launch_ball();
}
if (ImGui::MenuItem("Pause/Resume Game", "F3"))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Pause_Resume_Game), "F3"))
{
pause();
}
ImGui::Separator();
if (ImGui::MenuItem("High Scores...", nullptr, false, HighScoresEnabled))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_High_Scores), nullptr, false, HighScoresEnabled))
{
pause(false);
pb::high_scores();
}
if (ImGui::MenuItem("Demo", nullptr, DemoActive))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Demo), nullptr, DemoActive))
{
end_pause();
pb::toggle_demo();
}
if (ImGui::MenuItem("Exit"))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Exit)))
{
SDL_Event event{SDL_QUIT};
SDL_PushEvent(&event);
@@ -407,45 +440,58 @@ void winmain::RenderUi()
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Options"))
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Options)))
{
if (ImGui::MenuItem("Show Menu", "F9", Options.ShowMenu))
{
options::toggle(Menu1::Show_Menu);
}
if (ImGui::MenuItem("Full Screen", "F4", Options.FullScreen))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Full_Screen), "F4", Options.FullScreen))
{
options::toggle(Menu1::Full_Screen);
}
if (ImGui::BeginMenu("Select Players"))
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Select_Players)))
{
if (ImGui::MenuItem("1 Player", nullptr, Options.Players == 1))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_1Player), nullptr, Options.Players == 1))
{
options::toggle(Menu1::OnePlayer);
new_game();
}
if (ImGui::MenuItem("2 Players", nullptr, Options.Players == 2))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_2Players), nullptr, Options.Players == 2))
{
options::toggle(Menu1::TwoPlayers);
new_game();
}
if (ImGui::MenuItem("3 Players", nullptr, Options.Players == 3))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_3Players), nullptr, Options.Players == 3))
{
options::toggle(Menu1::ThreePlayers);
new_game();
}
if (ImGui::MenuItem("4 Players", nullptr, Options.Players == 4))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_4Players), nullptr, Options.Players == 4))
{
options::toggle(Menu1::FourPlayers);
new_game();
}
ImGui::EndMenu();
}
if (ImGui::MenuItem("Player Controls...", "F8"))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Player_Controls), "F8"))
{
pause(false);
options::ShowControlDialog();
}
if (ImGui::BeginMenu("Language"))
{
auto currentLanguage = translations::GetCurrentLanguage();
for (auto &item : translations::Languages)
{
if (ImGui::MenuItem(item.DisplayName, nullptr, currentLanguage->Language == item.Language))
{
translations::SetCurrentLanguage(item.ShortName);
winmain::Restart();
}
}
ImGui::EndMenu();
}
ImGui::Separator();
if (ImGui::BeginMenu("Audio"))
@@ -472,7 +518,7 @@ void winmain::RenderUi()
}
ImGui::Separator();
if (ImGui::MenuItem("Music", "F6", Options.Music))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_Music), "F6", Options.Music))
{
options::toggle(Menu1::Music);
}
@@ -487,6 +533,10 @@ void winmain::RenderUi()
if (ImGui::BeginMenu("Graphics"))
{
if (ImGui::MenuItem("Change Font"))
{
font_selection::ShowDialog();
}
if (ImGui::MenuItem("Uniform Scaling", nullptr, Options.UniformScaling))
{
options::toggle(Menu1::WindowUniformScale);
@@ -543,10 +593,18 @@ void winmain::RenderUi()
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Table Resolution"))
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Table_Resolution)))
{
char buffer[20]{};
auto maxResText = pinball::get_rc_string(fullscrn::GetMaxResolution() + 2030, 0);
Msg resolutionStringId = Msg::Menu1_UseMaxResolution_640x480;
switch(fullscrn::GetMaxResolution()) {
case 0: resolutionStringId = Msg::Menu1_UseMaxResolution_640x480; break;
case 1: resolutionStringId = Msg::Menu1_UseMaxResolution_800x600; break;
case 2: resolutionStringId = Msg::Menu1_UseMaxResolution_1024x768; break;
}
auto maxResText = pinball::get_rc_string(resolutionStringId);
if (ImGui::MenuItem(maxResText, nullptr, Options.Resolution == -1))
{
options::toggle(Menu1::MaximumResolution);
@@ -574,7 +632,7 @@ void winmain::RenderUi()
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help"))
if (ImGui::BeginMenu(pinball::get_rc_string(Msg::Menu1_Help)))
{
#ifndef NDEBUG
if (ImGui::MenuItem("ImGui Demo", nullptr, ShowImGuiDemo))
@@ -633,7 +691,7 @@ void winmain::RenderUi()
}
ImGui::Separator();
if (ImGui::MenuItem("About Pinball"))
if (ImGui::MenuItem(pinball::get_rc_string(Msg::Menu1_About_Pinball)))
{
pause(false);
ShowAboutDialog = true;
@@ -648,11 +706,15 @@ void winmain::RenderUi()
a_dialog();
high_score::RenderHighScoreDialog();
font_selection::RenderDialog();
if (ShowSpriteViewer)
render::SpriteViewer(&ShowSpriteViewer);
options::RenderControlDialog();
if (DispGRhistory)
RenderFrameTimeDialog();
// Print game texts on the sidebar
gdrv::grtext_draw_ttext_in_box();
}
int winmain::event_handler(const SDL_Event* event)
@@ -924,8 +986,8 @@ void winmain::memalloc_failure()
{
midi::music_stop();
Sound::Close();
char* caption = pinball::get_rc_string(170, 0);
char* text = pinball::get_rc_string(179, 0);
const char* caption = pinball::get_rc_string(Msg::STRING270);
const char* text = pinball::get_rc_string(Msg::STRING279);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, caption, text, MainWindow);
std::exit(1);
}
@@ -935,13 +997,13 @@ void winmain::a_dialog()
if (ShowAboutDialog == true)
{
ShowAboutDialog = false;
ImGui::OpenPopup("About");
ImGui::OpenPopup(pinball::get_rc_string(Msg::STRING204));
}
bool unused_open = true;
if (ImGui::BeginPopupModal("About", &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
if (ImGui::BeginPopupModal(pinball::get_rc_string(Msg::STRING204), &unused_open, ImGuiWindowFlags_AlwaysAutoResize))
{
ImGui::TextUnformatted("3D Pinball for Windows - Space Cadet");
ImGui::TextUnformatted(pinball::get_rc_string(Msg::STRING139));
ImGui::TextUnformatted("Original game by Cinematronics, Microsoft");
ImGui::Separator();