Added experimental translation support.

Added Russian translation.
Ref issues #28, #56.
This commit is contained in:
Muzychenko Andrey 2021-10-24 18:23:46 +03:00
parent cf8b53de01
commit 502fc71afc
7 changed files with 113 additions and 8 deletions

View File

@ -3737,7 +3737,7 @@ void control::SecretMissionYellowController(int code, TPinballComponent* caller)
void control::SelectMissionController(int code, TPinballComponent* caller) void control::SelectMissionController(int code, TPinballComponent* caller)
{ {
char Buffer[64]; char Buffer[128];
switch (code) switch (code)
{ {

View File

@ -3,6 +3,7 @@
#include "fullscrn.h" #include "fullscrn.h"
#include "memory.h" #include "memory.h"
#include "options.h"
#include "pinball.h" #include "pinball.h"
#include "winmain.h" #include "winmain.h"
@ -445,10 +446,24 @@ void gdrv::grtext_draw_ttext_in_box(LPCSTR text, int xOff, int yOff, int width,
sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue); sscanf_s(fontColor, "%d %d %d", &grtext_red, &grtext_green, &grtext_blue);
} }
// DEFAULT_CHARSET in unicode build.
int charset;
switch (options::Options.Language)
{
default:
case Languages::English:
charset = ANSI_CHARSET;
break;
case Languages::Russian:
charset = RUSSIAN_CHARSET;
break;
}
// Default font does not scale well // Default font does not scale well
auto hNewFont = CreateFont(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, auto hNewFont = CreateFont(fontSize, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Arial"); charset, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
HFONT hOldFont = (HFONT)SelectObject(dc, hNewFont); DEFAULT_PITCH | FF_SWISS, "Arial");
HFONT hOldFont = static_cast<HFONT>(SelectObject(dc, hNewFont));
int prevMode = SetBkMode(dc, TRANSPARENT); int prevMode = SetBkMode(dc, TRANSPARENT);
COLORREF color = SetTextColor(dc, grtext_red | grtext_green << 8 | grtext_blue << 16); COLORREF color = SetTextColor(dc, grtext_red | grtext_green << 8 | grtext_blue << 16);

View File

@ -1,4 +1,4 @@
#include "pch.h" #include "pch.h"
#include "options.h" #include "options.h"
#include "fullscrn.h" #include "fullscrn.h"
@ -68,9 +68,14 @@ short options::vk_list[28]
-1 -1
}; };
void options::init(HMENU menuHandle) LanguageMenuEntry options::LanguageMenu[]
{
{L"English", Languages::English},
{L"Русский", Languages::Russian},
};
void options::ReadOptions()
{ {
MenuHandle = menuHandle;
Options.Sounds = 1; Options.Sounds = 1;
Options.Music = 0; Options.Music = 0;
Options.FullScreen = 0; Options.FullScreen = 0;
@ -110,6 +115,45 @@ void options::init(HMENU menuHandle)
Options.UniformScaling = get_int(nullptr, "Uniform scaling", true); Options.UniformScaling = get_int(nullptr, "Uniform scaling", true);
Options.AlternativeRender = get_int(nullptr, "Alternative Render", false); Options.AlternativeRender = get_int(nullptr, "Alternative Render", false);
auto defaultLanguage = Languages::English;
auto language = static_cast<Languages>(get_int(nullptr, "Language", static_cast<int>(defaultLanguage)));
bool languageDefined = false;
for (auto menuEntry : LanguageMenu)
{
if (menuEntry.Language == language)
{
languageDefined = true;
break;
}
}
if (!languageDefined)
language = defaultLanguage;
Options.Language = language;
// Alternative approaches: resource DLLs, single-language builds.
// SetThreadUILanguage does not work properly on Windows XP.
bool winXp = false;
OSVERSIONINFO version{};
version.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
#pragma warning (disable : 4996) // XP has no versionhelpers.h
if (GetVersionEx(&version))
#pragma warning (default : 4996)
{
if (version.dwMajorVersion < 6)
winXp = true;
}
if (winXp)
SetThreadLocale(MAKELCID(static_cast<LANGID>(Options.Language), SORT_DEFAULT));
else
SetThreadUILanguage(static_cast<LANGID>(Options.Language));
}
void options::init(HMENU menuHandle)
{
MenuHandle = menuHandle;
menu_check(Menu1_Sounds, Options.Sounds); menu_check(Menu1_Sounds, Options.Sounds);
Sound::Enable(0, 7, Options.Sounds); Sound::Enable(0, 7, Options.Sounds);
menu_check(Menu1_Music, Options.Music); menu_check(Menu1_Music, Options.Music);
@ -136,6 +180,21 @@ void options::init(HMENU menuHandle)
} }
update_resolution_menu(); update_resolution_menu();
// Add language menu from code to decouple it from rc.
// AppendMenuW works with A window
auto hSubmenu = CreatePopupMenu();
auto index = Menu1_Language;
for (auto menuEntry : LanguageMenu)
{
UINT flags = MF_STRING;
if (menuEntry.Language == Options.Language)
flags |= MF_CHECKED;
AppendMenuW(hSubmenu, flags, index++, menuEntry.Name);
}
auto optionsMenu = GetSubMenu(MenuHandle, 1);
AppendMenu(optionsMenu, MF_STRING | MF_POPUP, reinterpret_cast<UINT_PTR>(hSubmenu), "Language");
} }
void options::uninit() void options::uninit()
@ -153,6 +212,7 @@ void options::uninit()
set_int(nullptr, "Screen Resolution", Options.Resolution); set_int(nullptr, "Screen Resolution", Options.Resolution);
set_int(nullptr, "Uniform scaling", Options.UniformScaling); set_int(nullptr, "Uniform scaling", Options.UniformScaling);
set_int(nullptr, "Alternative Render", Options.AlternativeRender); set_int(nullptr, "Alternative Render", Options.AlternativeRender);
set_int(nullptr, "Language", static_cast<int>(Options.Language));
} }
void options::path_init(LPCSTR regPath) void options::path_init(LPCSTR regPath)
@ -356,6 +416,13 @@ void options::toggle(UINT uIDCheckItem)
default: default:
break; break;
} }
if (uIDCheckItem >= Menu1_Language && uIDCheckItem < Menu1_LanguageMax)
{
auto languageId = uIDCheckItem - Menu1_Language;
Options.Language = LanguageMenu[languageId].Language;
winmain::Restart();
}
} }
void options::update_resolution_menu() void options::update_resolution_menu()

View File

@ -1,5 +1,18 @@
#pragma once #pragma once
#include "pinball.h" #include "pinball.h"
#include "resource.h"
enum class Languages
{
English = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
Russian = MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT),
};
struct LanguageMenuEntry
{
LPCWSTR Name;
Languages Language;
};
struct optionsStruct struct optionsStruct
{ {
@ -24,12 +37,14 @@ struct optionsStruct
int Resolution; int Resolution;
bool UniformScaling; bool UniformScaling;
bool AlternativeRender; bool AlternativeRender;
Languages Language;
}; };
class options class options
{ {
public: public:
static void ReadOptions();
static void init(HMENU menuHandle); static void init(HMENU menuHandle);
static void uninit(); static void uninit();
static void path_init(LPCSTR regPath); static void path_init(LPCSTR regPath);
@ -57,4 +72,5 @@ private:
static HMENU MenuHandle; static HMENU MenuHandle;
static winhelp_entry keymap_help[18]; static winhelp_entry keymap_help[18];
static short vk_list[28]; static short vk_list[28];
static LanguageMenuEntry LanguageMenu[Menu1_LanguageMax - Menu1_Language];
}; };

View File

@ -241,6 +241,8 @@
#define DLG_HIGHSCORES_EditName4 604 #define DLG_HIGHSCORES_EditName4 604
#define DLG_HIGHSCORES_EditName5 605 #define DLG_HIGHSCORES_EditName5 605
#define Menu1_AlternativeRender 601 #define Menu1_AlternativeRender 601
#define Menu1_Language 700
#define Menu1_LanguageMax 702
// Next default values for new objects // Next default values for new objects
// //

View File

@ -47,6 +47,7 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
++memory::critical_allocation; ++memory::critical_allocation;
auto optionsRegPath = pinball::get_rc_string(165, 0); auto optionsRegPath = pinball::get_rc_string(165, 0);
options::path_init(optionsRegPath); options::path_init(optionsRegPath);
options::ReadOptions();
auto regSpaceCadet = pinball::get_rc_string(166, 0); auto regSpaceCadet = pinball::get_rc_string(166, 0);
if (options::get_int(regSpaceCadet, "Table Version", 1) <= 1) if (options::get_int(regSpaceCadet, "Table Version", 1) <= 1)
@ -223,10 +224,10 @@ int winmain::WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi
auto dt = static_cast<float>(curTime - prevTime) * 0.001f; auto dt = static_cast<float>(curTime - prevTime) * 0.001f;
if (!options::Options.AlternativeRender) if (!options::Options.AlternativeRender)
sprintf_s(buf, "Frames/sec = %02.02f", 300.0f / dt); sprintf_s(buf, "Frames/sec = %02.02f", 300.0f / dt);
else else
{ {
sprintf_s(buf, "Updates/sec = %02.02f Frames/sec = %02.02f", sprintf_s(buf, "Updates/sec = %02.02f Frames/sec = %02.02f",
300.0f / dt, pb::frameCounter / dt); 300.0f / dt, pb::frameCounter / dt);
pb::frameCounter = 0; pb::frameCounter = 0;
} }
@ -665,6 +666,10 @@ LRESULT CALLBACK winmain::message_handler(HWND hWnd, UINT Msg, WPARAM wParam, LP
default: default:
break; break;
} }
if (wParam >= Menu1_Language && wParam < Menu1_LanguageMax)
options::toggle(wParamI);
return DefWindowProcA(hWnd, Msg, wParam, lParam); return DefWindowProcA(hWnd, Msg, wParam, lParam);
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
if (pb::game_mode) if (pb::game_mode)