Adding New Languages to RetroArch¶
While translation is handled via the Crowdin1 platform (more here), RetroArch's code must be adjusted to display new languages.
Files to change¶
msg_hash.c
msg_hash.h
retroarch.c
translation_defines.h
intl/msg_hash_us.h
menu/menu_setting.c
tasks/task_translation.c
libretro-common/include/libretro.h
Every new language must first be added to the project on Crowdin. This will ensure that a corresponding
intl/msg_hash_xx.h
file is created. Requests are accepted at the#retroarch-translations
channel of the RetroArch Discord2.
Main Instructions¶
To add a language with the English name XXXXX
and two-letter code xx
(be sure to use the same one as in the corresponding intl/msg_hash_xx.h
file) follow these steps:
- Open
libretro-common/include/libretro.h
.- Add a
RETRO_LANGUAGE_XXXXX
item to theretro_language
enum just aboveRETRO_LANGUAGE_LAST
, using the next available integer value.Do not rearrange the elements of this list! This would break the language association for the cores!
- Add a
- Open
msg_hash.h
.- Check if a
MENU_ENUM_LABEL_VALUE_LANG_XXXXX
item for your language is present in themsg_hash_enums
enum; if not, add it.
- Check if a
- Open
msg_hash.c
.- Add the following block inside the
get_user_language_iso639_1(bool limit)
function: - Add the following block inside the
msg_hash_to_str(enum msg_hash_enums msg)
function: - Add a new static function:
- Add the following block inside the
- Decide if
intl/msg_hash_xx.h
should use UTF-8 + BOM encoding. See the section below. - Open
intl/msg_hash_us.h
.- Check if the following block is present, where
Yyyyy
is the native name of the language and if not, add it:
- Check if the following block is present, where
- Open
menu/menu_setting.c
.- Add the following assignment to the
setting_get_string_representation_uint_user_language()
function, beforeif (*msg_hash_get_uint(MSG_HASH_USER_LANGUAGE) == RETRO_LANGUAGE_ENGLISH)
statement: - Add the following block inside the
setting_get_string_representation_uint_ai_service_lang()
function:
- Add the following assignment to the
- Open
retroarch.c
.- Add your language to
enum retro_language retroarch_get_language_from_iso(const char *iso639)
:
- Add your language to
- Open
tasks/task_translation.c
.- Add the following block inside the
ai_service_get_str(enum translation_lang id)
function:
- Add the following block inside the
- Open
translation_defines.h
.- Add your language to the
translation_lang
enum betweenTRANSLATION_LANG_DONT_CARE
andTRANSLATION_LANG_LAST
items:
- Add your language to the
Optional Adjustments¶
Generating custom font for RGUI¶
The tutorial down below is taken from trngaje's page.
First of all, I will explain the basic font, English font. It was 5x10 in size at first.
If you analyze the first letter of !… hexadecimal value
0x80, 0x10, 0x42, 0x08, 0x20, 0x00, 0x00,
Convert to Binary
Place it in a little endian and cut it into 5 pixels
The source code in retroarch for this is as follows.
unsigned font_pixel = x + y * FONT_WIDTH;
uint8_t rem = 1 << (font_pixel & 7);
unsigned offset = font_pixel >> 3;
uint8_t col = (bitmap_bin[FONT_OFFSET(letter) + offset] & rem) ? 0xff : 0;
The font was recreated by IlDucci’s request to improve the second Cyrillic language display error. It was 6x10 in size at first.
Each letter is separated by 16 pixels, of which only 6x10 is a meaningful area.
For this purpose, I created a conversion program using the SDL function.
It can be generated simply as follows.
Please refer to the location below for the code to build.
https://github.com/trngaje/png2c
You can download prebuilt images for Windows from the path below. https://github.com/trngaje/png2c/releases/tag/windows_64bit_png2c_220924
unzip windows_64bit_png2c_prebuild_220924.zip
RGUI Compatibility¶
To make the new language usable with the RGUI menu driver:
- Open
menu/drivers/rgui.c
. - Navigate to the
rgui_fonts_init(rgui_t *rgui)
function. - Add
case RETRO_LANGUAGE_XXXXX:
to- the extended ASCII section if the new language uses the Basic Latin/ASCII + Latin-1 Supplement range of UTF-8 or
- any other present language the new language shares the alphabet with (like Russian).
- If a new language was added, it is important to compile RetroArch with the changes and ensure the new language works correctly with RGUI.
- If your language uses a different range of symbols, an RGUI compatible font must be added first. This is an extensive process, which is outside the scope of this article.
Enabling new languages in cores¶
Adding a language to RetroArch does not automatically enable it for the core options. To do that for cores which have been added to Crowdin, follow these steps:
- Locate the
libretro.h
file and add aRETRO_LANGUAGE_XXXXX
item to theretro_language
enum exactly the same as was done for RetroArch.- Alternatively, overwrite this file with the
libretro-common/include/libretro.h
file from RetroArch's code.
- Alternatively, overwrite this file with the
- Locate the
libretro_core_options.h
file and open it.- Add
&options_xx,
at the end of theretro_core_options_v2
struct. Remember to keep the same order as in theretro_language
enum.
- Add
Adding cores to Crowdin is a whole other elaborate process and, currently, can only be performed by a Crowdin manager. Suggestions/Requests can be submitted on Discord to DisasterMo#0389.
Narrator support¶
- For Mac. (compatible with say)
- Open
frontend/drivers/platform_darwin.m
. - Go to
accessibility_mac_language_code(const char* language)
function. Check if the following block is present, whereYyyyy
is the voice name for the language and if not, add it beforereturn ""
:
- Open
- For Linux. (compatible with espeak)
- Open
frontend/drivers/platform_unix.c
. - Go to
accessibility_unix_language_code(const char* language)
function. Check if the following block is present, whereyyy
is the Identifier for the language and if not, add it before/* default voice as fallback */
:
- Open
- For Windows. (OS compatiable)
- Open
frontend/drivers/platform_win32.c
. - Go to
accessibility_win_language_code(const char* language)
function. Check if the following block is present, whereYyyyy
is the voice name for the language and if not, add it beforereturn ""
:
- Open
Encoding of translation files¶
Translation files (intl/msg_hash_xx.h
) in general must be UTF-8 encoded.
For some languages, these files need to have a "UTF-8 Unicode (with BOM)" encoding. This can be done using the 'Encoding' option of editors like Notepad++ and Notepadqq. AFAIK, this is because of a requirement of the MSVC compilers for the Windows platform. Examples of this as of now are:
msg_hash_ar.c
msg_hash_chs.h
msg_hash_cht.h
msg_hash_ja.h
msg_hash_ko.h
msg_hash_pl.h
msg_hash_ru.h
msg_hash_vn.h
Be careful when creating and editing your new translation files, as some text editors do strip the BOM without warning.
Examples¶
Adding languages to RetroArch¶
-
Arabic:
-
Indonesian, Swedish and Ukrainian (+RGUI):
Enabling new languages for cores¶
Translation¶
If you speak the target language xx
then you could start translating on Crowdin.
Instructions and recommended reading for that can be found here.
Please do not change the
intl/msg_hash_xx.h
files directly!
Starting from early 2023, the help texts that were located in intl/msg_hash_xx.c
files are also included on Crowdin. If you have translation efforts in msg_hash_xx.c
file from an earlier date, you can copy them to Crowdin, with following caveats:
* Individual line breaks (\n) at the end of each line are not required, current menu drivers will break lines automatically. Line break may be used as a paragraph separator, if text is long.
* Make sure translations still matches the current source text, as several of those were updated during the refactor.
* Do not exceed maximum line length (500 characters).
* The Crowdin translations for these strings will only take effect when the definition is removed from intl/msg_hash_xx.c
.
See also¶
-
https://crowdin.com/ - RetroArch and libretro are not affiliated in any way with Crowdin. ↩
-
The official RetroArch Discord server: https://ra-link.web.app/discord ↩