feat(windows64): add full language selection support with Russian localisation

## Language selection UI
- UIScene_SettingsOptionsMenu: enable _ENABLE_LANGUAGE_SELECT for _WINDOWS64
  so the Language button appears in the Settings menu on Windows
- UIScene_LanguageSelector.h: expose Simplified Chinese, Slovak and Czech
  language buttons on Windows64 (previously Durango-only)

## Windows64 XGetLanguage / XGetLocale implementation (Extrax64Stubs.cpp)
- Replace the stub XGetLanguage(){ return 1; } / XGetLocale(){ return 0; }
  with a real implementation that:
    1. First checks for an in-game override stored in GameSettingsA
       (SetMinecraftLanguage / SetMinecraftLocale)
    2. Falls back to GetUserDefaultLocaleName() and maps it to the
       appropriate XC_LANGUAGE_ / XC_LOCALE_ constant
  All locale regions (de-DE/AT/CH, fr-FR/CA/BE/CH, es-ES/MX/...,
  zh-CN/TW/HK, pt-PT/BR, no/nb/nn, nl-NL/BE, cs-CZ, sk-SK, el-GR,
  ru-RU, sv-SE, tr-TR, fi-FI, da-DK, ko-KR, ja-JP, it-IT, pl-PL)
  are handled.

## UIController.cpp fixes
- Fix typo _WINDOW64 -> _WINDOWS64 in reloadSkinThreadProc that caused
  NavigateBack() to be called after skin reload on Windows, crashing the game
- SetupFont(): always trigger eAppAction_ReloadFont when the font type is
  unchanged but the language changed (previously only triggered while in-game),
  so changing language from the main menu now refreshes the UI immediately

## Consoles_App.cpp
- getLocale(): add _WINDOWS64 to the #if guard for extended language support
  (Danish, Finnish, Czech, Slovak, Greek) so those locales resolve correctly

## Russian localisation (languages.loc + MediaWindows64.arc)
- Add IDS_LANG_SLOVAK (2286) and IDS_LANG_CZECH (2287) to strings.h
- Add Slovak and Czech display names to stringsLanguages.xml
- Build a complete Windows64-native Russian string block by mapping
  string names from Durango/Orbis/PS3/PSVita ru-RU XML files to the
  Windows64 integer IDs defined in strings.h (2283/2288 strings translated,
  remaining 5 use English fallback)
- Inject the ru-RU block into Windows64Media/Media/languages.loc and
  update Common/Media/MediaWindows64.arc accordingly
This commit is contained in:
Leeksov 2026-03-14 17:07:29 +03:00
parent 4d200a589d
commit afd6499811
9 changed files with 115 additions and 6 deletions

View file

@ -9776,7 +9776,7 @@ void CMinecraftApp::getLocale(vector<wstring> &vecWstrLocales)
locales.push_back(eMCLang_zhCN);
break;
#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO
#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ || defined _DURANGO || defined _WINDOWS64
case XC_LANGUAGE_DANISH:
locales.push_back(eMCLang_daDA);
locales.push_back(eMCLang_daDK);

View file

@ -392,8 +392,8 @@ void UIController::SetupFont()
if (m_eTargetFont == m_eCurrentFont)
{
// 4J-JEV: If we're ingame, reload the font to update all the text.
if (app.GetGameStarted()) app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ReloadFont);
// 4J-JEV: Font type unchanged but language changed - always reload UI to refresh strings.
app.SetAction(ProfileManager.GetPrimaryPad(), eAppAction_ReloadFont);
return;
}
@ -708,7 +708,7 @@ int UIController::reloadSkinThreadProc(void* lpParam)
controller->m_groups[eUIGroup_Fullscreen]->ReloadAll();
// 4J Stu - Don't do this on windows, as we never navigated forwards to start with
#ifndef _WINDOW64
#ifndef _WINDOWS64
controller->NavigateBack(0, false, eUIScene_COUNT, eUILayer_Tooltips);
#endif
LeaveCriticalSection(&ms_reloadSkinCS);

View file

@ -16,7 +16,7 @@
#define HAS_LANGUAGE_KO_KR(exp) exp,
#define HAS_LANGUAGE_CN_TW(exp) exp,
#ifdef _DURANGO
#if defined(_DURANGO) || defined(_WINDOWS64)
#define HAS_LANGUAGE_CN_CN(exp) exp,
#define HAS_LANGUAGE_SK_SK(exp) exp,
#define HAS_LANGUAGE_CZ_CZ(exp) exp,

View file

@ -2,7 +2,7 @@
#include "UI.h"
#include "UIScene_SettingsOptionsMenu.h"
#if defined(_XBOX_ONE)
#if defined(_XBOX_ONE) || defined(_WINDOWS64)
#define _ENABLE_LANGUAGE_SELECT
#endif

View file

@ -544,8 +544,113 @@ void XMemDestroyDecompressionContext(XMEMDECOMPRESSION_CONTEXT Context)
//#ifndef __PS3__
#if !(defined _DURANGO || defined __PS3__ || defined __ORBIS__ || defined __PSVITA__)
#ifdef _WINDOWS64
DWORD XGetLanguage()
{
// If the player has explicitly selected a language in-game, honour that override
unsigned char ucLang = app.GetMinecraftLanguage(0);
if (ucLang != MINECRAFT_LANGUAGE_DEFAULT) return ucLang;
// Otherwise detect the Windows UI language and map it to an XC_LANGUAGE_ constant
WCHAR wchLocaleName[LOCALE_NAME_MAX_LENGTH];
GetUserDefaultLocaleName(wchLocaleName, LOCALE_NAME_MAX_LENGTH);
eMCLang eLang = static_cast<eMCLang>(app.get_eMCLang(wchLocaleName));
switch (eLang)
{
case eMCLang_jaJP:
return XC_LANGUAGE_JAPANESE;
case eMCLang_deDE:
case eMCLang_deAT:
case eMCLang_deCH:
return XC_LANGUAGE_GERMAN;
case eMCLang_frFR:
case eMCLang_frCA:
case eMCLang_frBE:
case eMCLang_frCH:
return XC_LANGUAGE_FRENCH;
case eMCLang_esES:
case eMCLang_esMX:
case eMCLang_laLAS:
case eMCLang_esAR:
case eMCLang_esCL:
case eMCLang_esCO:
case eMCLang_esUS:
return XC_LANGUAGE_SPANISH;
case eMCLang_itIT:
return XC_LANGUAGE_ITALIAN;
case eMCLang_koKR:
return XC_LANGUAGE_KOREAN;
case eMCLang_zhCHT:
case eMCLang_zhHK:
case eMCLang_zhTW:
case eMCLang_hant:
return XC_LANGUAGE_TCHINESE;
case eMCLang_ptPT:
case eMCLang_ptBR:
return XC_LANGUAGE_PORTUGUESE;
case eMCLang_plPL:
return XC_LANGUAGE_POLISH;
case eMCLang_ruRU:
return XC_LANGUAGE_RUSSIAN;
case eMCLang_svSV:
case eMCLang_svSE:
return XC_LANGUAGE_SWEDISH;
case eMCLang_trTR:
return XC_LANGUAGE_TURKISH;
case eMCLang_nbNO:
case eMCLang_noNO:
case eMCLang_nnNO:
return XC_LANGUAGE_BNORWEGIAN;
case eMCLang_nlNL:
case eMCLang_nlBE:
return XC_LANGUAGE_DUTCH;
case eMCLang_zhCN:
case eMCLang_zhSG:
case eMCLang_hans:
case eMCLang_csCS:
return XC_LANGUAGE_SCHINESE;
case eMCLang_fiFI:
return XC_LANGUAGE_FINISH;
case eMCLang_daDA:
case eMCLang_daDK:
return XC_LANGUAGE_DANISH;
case eMCLang_csCZ:
case eMCLang_enCZ:
return XC_LANGUAGE_CZECH;
case eMCLang_skSK:
case eMCLang_enSK:
return XC_LANGUAGE_SLOVAK;
case eMCLang_elEL:
case eMCLang_elGR:
case eMCLang_enGR:
return XC_LANGUAGE_GREEK;
case eMCLang_enGB:
case eMCLang_enIE:
case eMCLang_enAU:
case eMCLang_enNZ:
case eMCLang_enCA:
case eMCLang_enUS:
default:
return XC_LANGUAGE_ENGLISH;
}
}
DWORD XGetLocale()
{
// If the player has explicitly selected a locale in-game, honour that override
unsigned char ucLocale = app.GetMinecraftLocale(0);
if (ucLocale != MINECRAFT_LANGUAGE_DEFAULT) return ucLocale;
// Otherwise map the Windows UI locale to an XC_LOCALE_ constant
WCHAR wchLocaleName[LOCALE_NAME_MAX_LENGTH];
GetUserDefaultLocaleName(wchLocaleName, LOCALE_NAME_MAX_LENGTH);
return app.get_xcLang(wchLocaleName);
}
#else
DWORD XGetLanguage() { return 1; }
DWORD XGetLocale() { return 0; }
#endif
DWORD XEnableGuestSignin(BOOL fEnable) { return 0; }
#endif

View file

@ -37,4 +37,6 @@
<data name="IDS_LANG_GREEK"> <value>Greek</value> </data>
<data name="IDS_LANG_TURKISH"> <value>Turkish</value> </data>
<data name="IDS_LANG_SLOVAK"> <value>Slovak</value> </data>
<data name="IDS_LANG_CZECH"> <value>Czech</value> </data>
</root>

View file

@ -2189,6 +2189,8 @@
#define IDS_LANG_NORWEGIAN 2183
#define IDS_LANG_GREEK 2184
#define IDS_LANG_TURKISH 2185
#define IDS_LANG_SLOVAK 2286
#define IDS_LANG_CZECH 2287
#define IDS_LEADERBOARD_KILLS_EASY 2186
#define IDS_LEADERBOARD_KILLS_NORMAL 2187
#define IDS_LEADERBOARD_KILLS_HARD 2188