Adding Localization support (#159)

* Innitial commit

Localization for retro-go using a simple 0(n) lookup function called rg_gettext()

* adding language settings in options menu

* adding more gettext()

* new lookup function

* adding "For these changes to take effect you must restart your device." gui alert + fixing gettext() function

* modifying the gui dialog

* updating struct syntax

* update struct syntax (again)

* creating the python tool for localization

* updating tool + adding missing translations

* moving stuff to libs + starting writing readme

* adding missing "libs/localization" folder import in cmakelist + added the "fixme for rg_system"

* synthax adjust + moving back stuff from libs to retro-go

* removing trailing spaces

* adding the enum for language ids

* updating documentation according to the latest changes

* small tweaks

* Moved LOCALIZATION.md to the root folder

Whilst it is mostly relevant to libretro-go, it really is project-wide documentation.

* rg_localization: Got rid of the switch, made GUI dynamic

This makes adding a language more straightforward.

I kept the *msg *fr *en for now to avoid updating translations.h, but it could be replaced by the GCC extension as such:

[RG_LANG_EN] = "...",
[RG_LANG_FR] = "...",

So that adding a language is really just updating the enum...

* rg_localization: translations is const, we can use RG_COUNT

* rg_gui: Fixed language selection

* rg_localization: No need to validate rg_language in rg_gettext

It should always be valid, there's no need to validate it.

* rg_gui: Show language name in the log

* rg_localization: Got rid of the Translation struct

I am not 100% positive this is a good move...

Benefits:
- One less thing to change when adding a language
- Less code is always better

Cons:
- It doesn't make it clear what the "key" is (the english text)
- If in the future we need to add things like flags it will have to be returned to a struct

* updated python tool + updating translations

* added missing translations

* audio filter wrong translation

* fix : "a propose de retro-go"

---------

Co-authored-by: Alex Duchesne <ducalex007@gmail.com>
This commit is contained in:
Raphael Texier 2024-11-16 19:04:50 +01:00 committed by GitHub
parent a1d5d9e458
commit 7b4a99cba8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 1283 additions and 199 deletions

32
LOCALIZATION.md Normal file
View File

@ -0,0 +1,32 @@
This document describes the localization protocol used in Retro-go
# C files
translation.h contains the original messages (in english) and the corresponding translations ex:
````c
{
[RG_LANG_EN] = "Yes",
[RG_LANG_FR] = "Oui",
[RG_LANG_ES] = "Si",
},
````
If you want to add your own language :
You should update the enum accordingly (in rg_localization.h):
````c
typedef enum
{
RG_LANG_EN,
RG_LANG_FR,
RG_LANG_ES, // <-- to add spanish translation
RG_LANG_MAX
} rg_language_t;
````
# Python tool
`rg_locate_str.py` is a simple python tool that locate every string preceded by `_("` pattern in each file of Retro-go project
Then the tool compare theses strings to the ones in `translations.h` and put the missing ones in a .txt file called missing_translation.txt

View File

@ -360,19 +360,19 @@ void rg_netplay_init(netplay_callback_t callback)
bool rg_netplay_quick_start(void)
{
const char *status_msg = "Initializing...";
const char *status_msg = _("Initializing...");
const char *screen_msg = NULL;
// int timeout = 100;
rg_display_clear(0);
const rg_gui_option_t options[] = {
{1, "Host Game (P1)", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2, "Find Game (P2)", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{1, _("Host Game (P1)"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2, _("Find Game (P2)"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END
};
int ret = rg_gui_dialog("Netplay", options, 0);
int ret = rg_gui_dialog(_("Netplay"), options, 0);
if (ret == 1)
rg_netplay_start(NETPLAY_MODE_HOST);
@ -387,31 +387,31 @@ bool rg_netplay_quick_start(void)
{
case NETPLAY_STATUS_CONNECTED:
return remote_player->game_id == local_player->game_id
|| rg_gui_confirm("Netplay", "ROMs not identical. Continue?", 1);
|| rg_gui_confirm(_("Netplay"), _("ROMs not identical. Continue?"), 1);
break;
case NETPLAY_STATUS_HANDSHAKE:
status_msg = "Exchanging info...";
status_msg = _("Exchanging info...");
break;
case NETPLAY_STATUS_CONNECTING:
status_msg = "Connecting...";
status_msg = _("Connecting...");
break;
case NETPLAY_STATUS_DISCONNECTED:
status_msg = "Unable to find host!";
status_msg = _("Unable to find host!");
break;
case NETPLAY_STATUS_STOPPED:
status_msg = "Connection failed!";
status_msg = _("Connection failed!");
break;
case NETPLAY_STATUS_LISTENING:
status_msg = "Waiting for peer...";
status_msg = _("Waiting for peer...");
break;
default:
status_msg = "Unknown status...";
status_msg = _("Unknown status...");
}
if (screen_msg != status_msg)

View File

@ -41,6 +41,7 @@ static struct
#define SETTING_THEME "Theme"
#define SETTING_WIFI_ENABLE "Enable"
#define SETTING_WIFI_SLOT "Slot"
#define SETTING_LANGUAGE "Language"
static uint16_t *get_draw_buffer(int width, int height, rg_color_t fill_color)
{
@ -100,12 +101,26 @@ void rg_gui_init(void)
gui.screen_width = rg_display_get_info()->screen.width;
gui.screen_height = rg_display_get_info()->screen.height;
gui.draw_buffer = get_draw_buffer(gui.screen_width, 18, C_BLACK);
rg_gui_set_language_id(rg_settings_get_number(NS_GLOBAL, SETTING_LANGUAGE, RG_LANG_EN));
rg_gui_set_font(rg_settings_get_number(NS_GLOBAL, SETTING_FONTTYPE, RG_FONT_VERA_12));
rg_gui_set_theme(rg_settings_get_string(NS_GLOBAL, SETTING_THEME, NULL));
gui.show_clock = rg_settings_get_number(NS_GLOBAL, SETTING_CLOCK, 0);
gui.initialized = true;
}
bool rg_gui_set_language_id(int index)
{
if (rg_localization_set_language_id(index))
{
rg_settings_set_number(NS_GLOBAL, SETTING_LANGUAGE, index);
RG_LOGI("Language set to: %s (%d)", rg_localization_get_language_name(index), index);
return true;
}
rg_localization_set_language_id(RG_LANG_EN);
RG_LOGE("Invalid language id %d!", index);
return false;
}
bool rg_gui_set_theme(const char *theme_name)
{
char pathbuf[RG_PATH_MAX];
@ -954,8 +969,8 @@ bool rg_gui_confirm(const char *title, const char *message, bool default_yes)
const rg_gui_option_t options[] = {
{0, message, NULL, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, "", NULL, RG_DIALOG_FLAG_MESSAGE, NULL},
{1, "Yes", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{0, "No ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{1, _("Yes"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{0, _("No"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
return rg_gui_dialog(title, message ? options : options + 1, default_yes ? -2 : -1) == 1;
@ -966,7 +981,7 @@ void rg_gui_alert(const char *title, const char *message)
const rg_gui_option_t options[] = {
{0, message, NULL, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, "", NULL, RG_DIALOG_FLAG_MESSAGE, NULL},
{1, "OK", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{1, _("OK"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
rg_gui_dialog(title, message ? options : options + 1, -1);
@ -1003,17 +1018,17 @@ char *rg_gui_file_picker(const char *title, const char *path, bool (*validator)(
};
if (!title)
title = "Select file";
title = _("Select file");
if (none_option)
{
options.options[options.count++] = (rg_gui_option_t){0, "<None>", NULL, RG_DIALOG_FLAG_NORMAL, NULL};
options.options[options.count++] = (rg_gui_option_t){0, _("<None>"), NULL, RG_DIALOG_FLAG_NORMAL, NULL};
// options.options[options.count++] = (rg_gui_option_t)RG_DIALOG_SEPARATOR;
}
if (!rg_storage_scandir(path, file_picker_cb, &options, 0) || options.count < 1)
{
rg_gui_alert(title, "Folder is empty.");
rg_gui_alert(title, _("Folder is empty."));
return NULL;
}
@ -1151,13 +1166,13 @@ static rg_gui_event_t filter_update_cb(rg_gui_option_t *option, rg_gui_event_t e
}
if (mode == RG_DISPLAY_FILTER_OFF)
strcpy(option->value, "Off ");
strcpy(option->value, _("Off"));
if (mode == RG_DISPLAY_FILTER_HORIZ)
strcpy(option->value, "Horiz");
strcpy(option->value, _("Horiz"));
if (mode == RG_DISPLAY_FILTER_VERT)
strcpy(option->value, "Vert ");
strcpy(option->value, _("Vert"));
if (mode == RG_DISPLAY_FILTER_BOTH)
strcpy(option->value, "Both ");
strcpy(option->value, _("Both"));
return RG_DIALOG_VOID;
}
@ -1180,13 +1195,13 @@ static rg_gui_event_t scaling_update_cb(rg_gui_option_t *option, rg_gui_event_t
}
if (mode == RG_DISPLAY_SCALING_OFF)
strcpy(option->value, "Off ");
strcpy(option->value, _("Off"));
else if (mode == RG_DISPLAY_SCALING_FIT)
strcpy(option->value, "Fit ");
strcpy(option->value, _("Fit"));
else if (mode == RG_DISPLAY_SCALING_FULL)
strcpy(option->value, "Full ");
strcpy(option->value, _("Full"));
else if (mode == RG_DISPLAY_SCALING_ZOOM)
strcpy(option->value, "Zoom");
strcpy(option->value, _("Zoom"));
return RG_DIALOG_VOID;
}
@ -1239,7 +1254,7 @@ static rg_gui_event_t led_indicator_opt_cb(rg_gui_option_t *option, rg_gui_event
{
rg_system_set_indicator_mask(option->arg, !rg_system_get_indicator_mask(option->arg));
}
strcpy(option->value, rg_system_get_indicator_mask(option->arg) ? "On " : "Off");
strcpy(option->value, rg_system_get_indicator_mask(option->arg) ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -1248,12 +1263,12 @@ static rg_gui_event_t led_indicator_cb(rg_gui_option_t *option, rg_gui_event_t e
if (event == RG_DIALOG_ENTER)
{
const rg_gui_option_t options[] = {
{RG_INDICATOR_ACTIVITY_SYSTEM, "System activity", "-", RG_DIALOG_FLAG_NORMAL, &led_indicator_opt_cb},
{RG_INDICATOR_ACTIVITY_DISK, "Disk activity", "-", RG_DIALOG_FLAG_NORMAL, &led_indicator_opt_cb},
{RG_INDICATOR_POWER_LOW, "Low battery", "-", RG_DIALOG_FLAG_NORMAL, &led_indicator_opt_cb},
{RG_INDICATOR_ACTIVITY_SYSTEM, _("System activity"), "-", RG_DIALOG_FLAG_NORMAL, &led_indicator_opt_cb},
{RG_INDICATOR_ACTIVITY_DISK, _("Disk activity"), "-", RG_DIALOG_FLAG_NORMAL, &led_indicator_opt_cb},
{RG_INDICATOR_POWER_LOW, _("Low battery"), "-", RG_DIALOG_FLAG_NORMAL, &led_indicator_opt_cb},
RG_DIALOG_END,
};
rg_gui_dialog("LED options", options, 0);
rg_gui_dialog(_("LED options"), options, 0);
}
return RG_DIALOG_VOID;
}
@ -1266,7 +1281,7 @@ static rg_gui_event_t show_clock_cb(rg_gui_option_t *option, rg_gui_event_t even
rg_settings_set_number(NS_GLOBAL, SETTING_CLOCK, gui.show_clock);
return RG_DIALOG_REDRAW;
}
strcpy(option->value, gui.show_clock ? "On " : "Off");
strcpy(option->value, gui.show_clock ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -1339,6 +1354,35 @@ static rg_gui_event_t theme_cb(rg_gui_option_t *option, rg_gui_event_t event)
return RG_DIALOG_VOID;
}
static rg_gui_event_t language_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
int language_id = rg_localization_get_language_id();
const char *language_name = rg_localization_get_language_name(language_id);
if (event == RG_DIALOG_ENTER)
{
rg_gui_option_t options[RG_LANG_MAX + 1];
for (int i = 0; i < RG_LANG_MAX; i++)
options[i] = (rg_gui_option_t){i, rg_localization_get_language_name(i), NULL, RG_DIALOG_FLAG_NORMAL, NULL};
options[RG_LANG_MAX] = (rg_gui_option_t)RG_DIALOG_END;
int sel = rg_gui_dialog(_("Language"), options, language_id);
if (sel != RG_DIALOG_CANCELLED)
{
rg_gui_set_language_id(sel);
if (rg_gui_confirm(_("Language changed!"), _("For these changes to take effect you must restart your device.\nrestart now?"), true))
{
rg_system_exit();
}
language_id = sel;
language_name = rg_localization_get_language_name(sel);
}
return RG_DIALOG_REDRAW;
}
sprintf(option->value, "%s", language_name ? language_name : "???");
return RG_DIALOG_VOID;
}
static rg_gui_event_t border_update_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
if (event == RG_DIALOG_ENTER)
@ -1352,7 +1396,7 @@ static rg_gui_event_t border_update_cb(rg_gui_option_t *option, rg_gui_event_t e
}
}
char *border = rg_display_get_border();
sprintf(option->value, "%.9s", border ? rg_basename(border) : "None");
sprintf(option->value, "%.9s", border ? rg_basename(border) : _("None"));
free(border);
return RG_DIALOG_VOID;
}
@ -1362,7 +1406,7 @@ static void wifi_toggle_interactive(bool enable, int slot)
{
rg_network_state_t target_state = enable ? RG_NETWORK_CONNECTED : RG_NETWORK_DISCONNECTED;
int64_t timeout = rg_system_timer() + 20 * 1000000;
rg_gui_draw_message(enable ? "Connecting..." : "Disconnecting...");
rg_gui_draw_message(enable ? _("Connecting...") : _("Disconnecting..."));
rg_network_wifi_stop();
if (enable)
{
@ -1396,7 +1440,7 @@ static rg_gui_event_t wifi_status_cb(rg_gui_option_t *option, rg_gui_event_t eve
{
rg_network_t info = rg_network_get_info();
if (info.state != RG_NETWORK_CONNECTED)
strcpy(option->value, "Not connected");
strcpy(option->value, _("Not connected"));
else if (option->arg == 0x10)
strcpy(option->value, info.name);
else if (option->arg == 0x11)
@ -1411,7 +1455,7 @@ static rg_gui_event_t wifi_profile_cb(rg_gui_option_t *option, rg_gui_event_t ev
for (size_t i = 0; i < 5; i++)
{
rg_wifi_config_t config;
strncpy(labels[i], rg_network_wifi_read_config(i, &config) ? config.ssid : "(empty)", 32);
strncpy(labels[i], rg_network_wifi_read_config(i, &config) ? config.ssid : _("(empty)"), 32);
}
if (event == RG_DIALOG_ENTER)
{
@ -1423,7 +1467,7 @@ static rg_gui_event_t wifi_profile_cb(rg_gui_option_t *option, rg_gui_event_t ev
{4, "4", labels[4], RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
int sel = rg_gui_dialog("Wi-Fi Profile", options, slot);
int sel = rg_gui_dialog(_("Wi-Fi Profile"), options, slot);
if (sel != RG_DIALOG_CANCELLED)
{
rg_settings_set_number(NS_WIFI, SETTING_WIFI_ENABLE, 1);
@ -1435,7 +1479,7 @@ static rg_gui_event_t wifi_profile_cb(rg_gui_option_t *option, rg_gui_event_t ev
if (slot >= 0 && slot < RG_COUNT(labels))
sprintf(option->value, "%d - %s", slot, labels[slot]);
else
strcpy(option->value, "none");
strcpy(option->value, _("none"));
return RG_DIALOG_VOID;
}
@ -1443,7 +1487,7 @@ static rg_gui_event_t wifi_access_point_cb(rg_gui_option_t *option, rg_gui_event
{
if (event == RG_DIALOG_ENTER)
{
if (rg_gui_confirm("Wi-Fi AP", "Start access point?\n\nSSID: retro-go\nPassword: retro-go\n\nBrowse: http://192.168.4.1/", true))
if (rg_gui_confirm(_("Wi-Fi AP"), _("Start access point?\n\nSSID: retro-go\nPassword: retro-go\n\nBrowse: http://192.168.4.1/"), true))
{
wifi_toggle_interactive(true, 9000);
}
@ -1462,7 +1506,7 @@ static rg_gui_event_t wifi_enable_cb(rg_gui_option_t *option, rg_gui_event_t eve
wifi_toggle_interactive(enabled, rg_settings_get_number(NS_WIFI, SETTING_WIFI_SLOT, -1));
return RG_DIALOG_REDRAW;
}
strcpy(option->value, enabled ? "On " : "Off");
strcpy(option->value, enabled ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -1471,16 +1515,16 @@ static rg_gui_event_t wifi_cb(rg_gui_option_t *option, rg_gui_event_t event)
if (event == RG_DIALOG_ENTER)
{
const rg_gui_option_t options[] = {
{0x00, "Wi-Fi enable ", "-", RG_DIALOG_FLAG_NORMAL, &wifi_enable_cb },
{0x01, "Wi-Fi profile", "-", RG_DIALOG_FLAG_NORMAL, &wifi_profile_cb },
{0x00, _("Wi-Fi enable"), "-", RG_DIALOG_FLAG_NORMAL, &wifi_enable_cb },
{0x01, _("Wi-Fi profile"), "-", RG_DIALOG_FLAG_NORMAL, &wifi_profile_cb },
RG_DIALOG_SEPARATOR,
{0x02, "Wi-Fi access point", NULL, RG_DIALOG_FLAG_NORMAL, &wifi_access_point_cb},
{0x02, _("Wi-Fi access point"), NULL, RG_DIALOG_FLAG_NORMAL, &wifi_access_point_cb},
RG_DIALOG_SEPARATOR,
{0x10, "Network ", "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb },
{0x11, "IP address", "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb },
{0x10, _("Network"), "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb },
{0x11, _("IP address"), "-", RG_DIALOG_FLAG_MESSAGE, &wifi_status_cb },
RG_DIALOG_END,
};
rg_gui_dialog("Wifi Options", options, 0);
rg_gui_dialog(_("Wifi Options"), options, 0);
}
return RG_DIALOG_VOID;
}
@ -1493,33 +1537,34 @@ void rg_gui_options_menu(void)
rg_gui_option_t *opt = &options[0];
#ifdef RG_SCREEN_BACKLIGHT
*opt++ = (rg_gui_option_t){0, "Brightness", "-", RG_DIALOG_FLAG_NORMAL, &brightness_update_cb};
*opt++ = (rg_gui_option_t){0, _("Brightness"), "-", RG_DIALOG_FLAG_NORMAL, &brightness_update_cb};
#endif
*opt++ = (rg_gui_option_t){0, "Volume ", "-", RG_DIALOG_FLAG_NORMAL, &volume_update_cb};
*opt++ = (rg_gui_option_t){0, "Audio out ", "-", RG_DIALOG_FLAG_NORMAL, &audio_update_cb};
*opt++ = (rg_gui_option_t){0, _("Volume"), "-", RG_DIALOG_FLAG_NORMAL, &volume_update_cb};
*opt++ = (rg_gui_option_t){0, _("Audio out"), "-", RG_DIALOG_FLAG_NORMAL, &audio_update_cb};
// Global settings that aren't essential to show when inside a game
if (app->isLauncher)
{
*opt++ = (rg_gui_option_t){0, "Font type ", "-", RG_DIALOG_FLAG_NORMAL, &font_type_cb};
*opt++ = (rg_gui_option_t){0, "Theme ", "-", RG_DIALOG_FLAG_NORMAL, &theme_cb};
*opt++ = (rg_gui_option_t){0, "Show clock", "-", RG_DIALOG_FLAG_NORMAL, &show_clock_cb};
*opt++ = (rg_gui_option_t){0, "Timezone ", "-", RG_DIALOG_FLAG_NORMAL, &timezone_cb};
*opt++ = (rg_gui_option_t){0, _("Font type"), "-", RG_DIALOG_FLAG_NORMAL, &font_type_cb};
*opt++ = (rg_gui_option_t){0, _("Theme"), "-", RG_DIALOG_FLAG_NORMAL, &theme_cb};
*opt++ = (rg_gui_option_t){0, _("Show clock"), "-", RG_DIALOG_FLAG_NORMAL, &show_clock_cb};
*opt++ = (rg_gui_option_t){0, _("Timezone"), "-", RG_DIALOG_FLAG_NORMAL, &timezone_cb};
*opt++ = (rg_gui_option_t){0, _("Language"), "-", RG_DIALOG_FLAG_NORMAL, &language_cb};
#ifdef RG_GPIO_LED // Only show disk LED option if disk LED GPIO pin is defined
*opt++ = (rg_gui_option_t){0, "LED options", NULL, RG_DIALOG_FLAG_NORMAL, &led_indicator_cb};
*opt++ = (rg_gui_option_t){0, _("LED options"), NULL, RG_DIALOG_FLAG_NORMAL, &led_indicator_cb};
#endif
#ifdef RG_ENABLE_NETWORKING
*opt++ = (rg_gui_option_t){0, "Wi-Fi options", NULL, RG_DIALOG_FLAG_NORMAL, &wifi_cb};
*opt++ = (rg_gui_option_t){0, _("Wi-Fi options"), NULL, RG_DIALOG_FLAG_NORMAL, &wifi_cb};
#endif
}
// App settings that are shown only inside a game
else
{
*opt++ = (rg_gui_option_t){0, "Scaling", "-", RG_DIALOG_FLAG_NORMAL, &scaling_update_cb};
*opt++ = (rg_gui_option_t){0, " Factor", "-", RG_DIALOG_FLAG_HIDDEN, &custom_zoom_cb};
*opt++ = (rg_gui_option_t){0, "Filter", "-", RG_DIALOG_FLAG_NORMAL, &filter_update_cb};
*opt++ = (rg_gui_option_t){0, "Border", "-", RG_DIALOG_FLAG_NORMAL, &border_update_cb};
*opt++ = (rg_gui_option_t){0, "Speed", "-", RG_DIALOG_FLAG_NORMAL, &speedup_update_cb};
*opt++ = (rg_gui_option_t){0, _("Scaling"), "-", RG_DIALOG_FLAG_NORMAL, &scaling_update_cb};
*opt++ = (rg_gui_option_t){0, _("Factor"), "-", RG_DIALOG_FLAG_HIDDEN, &custom_zoom_cb};
*opt++ = (rg_gui_option_t){0, _("Filter"), "-", RG_DIALOG_FLAG_NORMAL, &filter_update_cb};
*opt++ = (rg_gui_option_t){0, _("Border"), "-", RG_DIALOG_FLAG_NORMAL, &border_update_cb};
*opt++ = (rg_gui_option_t){0, _("Speed"), "-", RG_DIALOG_FLAG_NORMAL, &speedup_update_cb};
}
size_t extra_options = get_dialog_items_count(app->options);
@ -1530,7 +1575,7 @@ void rg_gui_options_menu(void)
rg_audio_set_mute(true);
rg_gui_dialog("Options", options, 0);
rg_gui_dialog(_("Options"), options, 0);
rg_settings_commit();
rg_audio_set_mute(false);
@ -1543,15 +1588,15 @@ void rg_gui_about_menu(const rg_gui_option_t *extra_options)
// TODO: Add indicator whether or not the build is a release, and if it's official (built by me)
rg_gui_option_t options[20] = {
{0, "Version", (char *)app->version, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, "Date ", (char *)app->buildDate, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, "Target ", (char *)RG_TARGET_NAME, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, "Website", (char *)RG_PROJECT_WEBSITE, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, _("Version"), (char *)app->version, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, _("Date"), (char *)app->buildDate, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, _("Target"), (char *)RG_TARGET_NAME, RG_DIALOG_FLAG_MESSAGE, NULL},
{0, _("Website"), (char *)RG_PROJECT_WEBSITE, RG_DIALOG_FLAG_MESSAGE, NULL},
RG_DIALOG_SEPARATOR,
{4, "Options ", NULL, have_option_btn ? RG_DIALOG_FLAG_HIDDEN : RG_DIALOG_FLAG_NORMAL , NULL},
// {1, "View credits", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2, "Debug menu", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3, "Reset settings", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{4, _("Options "), NULL, have_option_btn ? RG_DIALOG_FLAG_HIDDEN : RG_DIALOG_FLAG_NORMAL , NULL},
// {1, _("View credits", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2, _("Debug menu"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3, _("Reset settings"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
@ -1566,7 +1611,7 @@ void rg_gui_about_menu(const rg_gui_option_t *extra_options)
while (true)
{
switch (rg_gui_dialog("About Retro-Go", options, 4))
switch (rg_gui_dialog(_("About Retro-Go"), options, 4))
{
case 1:
// FIXME: This should probably be a regular dialog so that it's scrollable!
@ -1576,7 +1621,7 @@ void rg_gui_about_menu(const rg_gui_option_t *extra_options)
rg_gui_debug_menu(NULL);
break;
case 3:
if (rg_gui_confirm("Reset all settings?", NULL, false)) {
if (rg_gui_confirm(_("Reset all settings?"), NULL, false)) {
rg_storage_delete(RG_BASE_PATH_CACHE);
rg_settings_reset();
rg_system_restart();
@ -1740,10 +1785,10 @@ int rg_gui_savestate_menu(const char *title, const char *rom_path, bool quick_re
const rg_app_t *app = rg_system_get_app();
rg_emu_states_t *savestates = rg_emu_get_states(rom_path ?: app->romPath, 4);
const rg_gui_option_t choices[] = {
{(intptr_t)&savestates->slots[0], "Slot 0", NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[1], "Slot 1", NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[2], "Slot 2", NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[3], "Slot 3", NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[0], _("Slot 0"), NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[1], _("Slot 1"), NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[2], _("Slot 2"), NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
{(intptr_t)&savestates->slots[3], _("Slot 3"), NULL, RG_DIALOG_FLAG_NORMAL, &slot_select_cb},
RG_DIALOG_END
};
int sel = 0;
@ -1768,16 +1813,16 @@ void rg_gui_game_menu(void)
{
bool have_option_btn = rg_input_get_key_mapping(RG_KEY_OPTION);
const rg_gui_option_t choices[] = {
{1000, "Save & Continue", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2000, "Save & Quit ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3001, "Load game ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3000, "Reset ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{1000, _("Save & Continue"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2000, _("Save & Quit"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3001, _("Load game"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3000, _("Reset"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
#ifdef RG_ENABLE_NETPLAY
{5000, "Netplay ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{5000, _("Netplay"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
#endif
{5500, "Options ", NULL, have_option_btn ? RG_DIALOG_FLAG_HIDDEN : RG_DIALOG_FLAG_NORMAL, NULL},
{6000, "About ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{7000, "Quit ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{5500, _("Options"), NULL, have_option_btn ? RG_DIALOG_FLAG_HIDDEN : RG_DIALOG_FLAG_NORMAL, NULL},
{6000, _("About"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{7000, _("Quit"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END
};
int slot, sel;
@ -1791,11 +1836,11 @@ void rg_gui_game_menu(void)
if (sel == 3000)
{
const rg_gui_option_t choices[] = {
{3002, "Soft reset", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3003, "Hard reset", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3002, _("Soft reset"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{3003, _("Hard reset"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END
};
sel = rg_gui_dialog("Reset Emulation?", choices, 0);
sel = rg_gui_dialog(_("Reset Emulation?"), choices, 0);
}
switch (sel)

View File

@ -93,6 +93,7 @@ struct rg_gui_option_s
#define TEXT_RECT(text, max) rg_gui_draw_text(-(max), 0, 0, (text), 0, 0, RG_TEXT_MULTILINE|RG_TEXT_DUMMY_DRAW)
void rg_gui_init(void);
bool rg_gui_set_language_id(int index);
void rg_gui_set_surface(rg_surface_t *surface);
bool rg_gui_set_font(int index);
bool rg_gui_set_theme(const char *name);

View File

@ -0,0 +1,43 @@
#include "rg_system.h"
#include "translations.h"
static int rg_language = RG_LANG_EN;
int rg_localization_get_language_id(void)
{
return rg_language;
}
bool rg_localization_set_language_id(int language_id)
{
if (language_id < 0 || language_id > RG_LANG_MAX - 1)
return false;
rg_language = language_id;
return true;
}
const char *rg_gettext(const char *text)
{
if (rg_language == 0 || text == NULL)
return text; // If rg_language is english or text is NULL, we can return self
for (size_t i = 0; i < RG_COUNT(translations); ++i)
{
if (strcmp(translations[i][0], text) == 0)
{
const char *msg = translations[i][rg_language];
// If the translation is missing, we return the original string
return msg ? msg : text;
}
}
return text; // if no translation found
}
const char *rg_localization_get_language_name(int language_id)
{
if (language_id < 0 || language_id > RG_LANG_MAX - 1)
return NULL;
return language_names[language_id];
}

View File

@ -0,0 +1,21 @@
#pragma once
#include <string.h>
#include <stdbool.h>
#define _(String) rg_gettext(String)
typedef enum
{
RG_LANG_EN = 0,
RG_LANG_FR,
//RG_LANG_ES,
RG_LANG_MAX
} rg_language_t;
// Lookup function
const char *rg_gettext(const char *msg);
int rg_localization_get_language_id(void);
bool rg_localization_set_language_id(int language_id);
const char *rg_localization_get_language_name(int language_id);

View File

@ -290,14 +290,14 @@ static void enter_recovery_mode(void)
RG_LOGW("Entering recovery mode...\n");
const rg_gui_option_t options[] = {
{0, "Reset all settings", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{1, "Reboot to factory ", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2, "Reboot to launcher", NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{0, _("Reset all settings"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{1, _("Reboot to factory "), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
{2, _("Reboot to launcher"), NULL, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
while (true)
{
switch (rg_gui_dialog("Recovery mode", options, -1))
switch (rg_gui_dialog(_("Recovery mode"), options, -1))
{
case 0:
rg_storage_delete(RG_BASE_PATH_CONFIG);
@ -416,6 +416,7 @@ rg_app_t *rg_system_init(int sampleRate, const rg_handlers_t *handlers, const rg
if (enterRecoveryMode)
{
rg_display_init();
//rg_settings_init(); FIXME: Find a way to get the user's language without loading all settings
rg_gui_init();
enter_recovery_mode();
}

View File

@ -24,6 +24,7 @@ extern "C" {
#define RTC_NOINIT_ATTR
#endif
#include "rg_localization.h"
#include "rg_audio.h"
#include "rg_display.h"
#include "rg_input.h"

View File

@ -0,0 +1,846 @@
#include "rg_localization.h"
static const char *language_names[RG_LANG_MAX] = {"English", "Francais"};
static const char *translations[][RG_LANG_MAX] =
{
{
[RG_LANG_EN] = "Never",
[RG_LANG_FR] = "Jamais",
},
{
[RG_LANG_EN] = "Always",
[RG_LANG_FR] = "Toujours",
},
{
[RG_LANG_EN] = "Composite",
[RG_LANG_FR] = "Composite",
},
{
[RG_LANG_EN] = "NES Classic",
[RG_LANG_FR] = "NES Classic",
},
{
[RG_LANG_EN] = "NTSC",
[RG_LANG_FR] = "NTSC",
},
{
[RG_LANG_EN] = "PVM",
[RG_LANG_FR] = "PVM",
},
{
[RG_LANG_EN] = "Smooth",
[RG_LANG_FR] = "Lisser",
},
{
[RG_LANG_EN] = "To start, try: 1 or * or #",
[RG_LANG_FR] = "Pour commencer, 1 ou * ou #",
},
{
[RG_LANG_EN] = "Full",
[RG_LANG_FR] = "Complet",
},
{
[RG_LANG_EN] = "Yes",
[RG_LANG_FR] = "Oui"
},
{
[RG_LANG_EN] = "Select file",
[RG_LANG_FR] = "Choisissez un fichier"
},
{
[RG_LANG_EN] = "Off",
[RG_LANG_FR] = "Off"
},
{
[RG_LANG_EN] = "Language",
[RG_LANG_FR] = "Langue"
},
{
[RG_LANG_EN] = "Language changed!",
[RG_LANG_FR] = "Changement de langue"
},
{
[RG_LANG_EN] = "For these changes to take effect you must restart your device.\nrestart now?",
[RG_LANG_FR] = "Pour que ces changements prennent effet, vous devez redemmarer votre appareil.\nRedemmarer maintenant ?"
},
{
[RG_LANG_EN] = "Wi-Fi profile",
[RG_LANG_FR] = "Profile Wi-Fi"
},
{
[RG_LANG_EN] = "Language",
[RG_LANG_FR] = "Langue"
},
{
[RG_LANG_EN] = "Options",
[RG_LANG_FR] = "Options"
},
{
[RG_LANG_EN] = "About Retro-Go",
[RG_LANG_FR] = "A propos de Retro-go"
},
{
[RG_LANG_EN] = "Reset all settings?",
[RG_LANG_FR] = "Reset tous les parametres"
},
{
[RG_LANG_EN] = "Initializing...",
[RG_LANG_FR] = "Initialisation..."
},
{
[RG_LANG_EN] = "Host Game (P1)",
[RG_LANG_FR] = "Host Game (P1)"
},
{
[RG_LANG_EN] = "Find Game (P2)",
[RG_LANG_FR] = "Find Game (P2)"
},
{
[RG_LANG_EN] = "Netplay",
[RG_LANG_FR] = "Netplay"
},
{
[RG_LANG_EN] = "ROMs not identical. Continue?",
[RG_LANG_FR] = "ROMs not identical. Continue?"
},
{
[RG_LANG_EN] = "Exchanging info...",
[RG_LANG_FR] = "Exchanging info..."
},
{
[RG_LANG_EN] = "Unable to find host!",
[RG_LANG_FR] = "Unable to find host!"
},
{
[RG_LANG_EN] = "Connection failed!",
[RG_LANG_FR] = "Connection failed!"
},
{
[RG_LANG_EN] = "Waiting for peer...",
[RG_LANG_FR] = "Waiting for peer..."
},
{
[RG_LANG_EN] = "Unknown status...",
[RG_LANG_FR] = "Unknown status..."
},
{
[RG_LANG_EN] = "On",
[RG_LANG_FR] = "On"
},
{
[RG_LANG_EN] = "Keyboard",
[RG_LANG_FR] = "Clavier"
},
{
[RG_LANG_EN] = "Joystick",
[RG_LANG_FR] = "Joystick"
},
{
[RG_LANG_EN] = "Input",
[RG_LANG_FR] = "Entree"
},
{
[RG_LANG_EN] = "Crop",
[RG_LANG_FR] = "Couper"
},
{
[RG_LANG_EN] = "BIOS file missing!",
[RG_LANG_FR] = "Fichier BIOS manquant"
},
{
[RG_LANG_EN] = "YM2612 audio ",
[RG_LANG_FR] = "YM2612 audio "
},
{
[RG_LANG_EN] = "SN76489 audio",
[RG_LANG_FR] = "SN76489 audio"
},
{
[RG_LANG_EN] = "Z80 emulation",
[RG_LANG_FR] = "Emulation Z80"
},
{
[RG_LANG_EN] = "Launcher options",
[RG_LANG_FR] = "Options du lanceur"
},
{
[RG_LANG_EN] = "Date",
[RG_LANG_FR] = "Date"
},
{
[RG_LANG_EN] = "Files:",
[RG_LANG_FR] = "Fichiers:"
},
{
[RG_LANG_EN] = "Download complete!",
[RG_LANG_FR] = "Telechargement termine"
},
{
[RG_LANG_EN] = "Reboot to flash?",
[RG_LANG_FR] = "Redemarrer"
},
{
[RG_LANG_EN] = "Available Releases",
[RG_LANG_FR] = "Maj disponibles"
},
{
[RG_LANG_EN] = "Received empty list!",
[RG_LANG_FR] = "Liste vide recue"
},
{
[RG_LANG_EN] = "Gamma Boost",
[RG_LANG_FR] = "Boost Gamma"
},
{
[RG_LANG_EN] = "Day",
[RG_LANG_FR] = "Jour"
},
{
[RG_LANG_EN] = "Hour",
[RG_LANG_FR] = "Heure"
},
{
[RG_LANG_EN] = "Min",
[RG_LANG_FR] = "Min"
},
{
[RG_LANG_EN] = "Sec",
[RG_LANG_FR] = "Sec"
},
{
[RG_LANG_EN] = "Sync",
[RG_LANG_FR] = "Synchro"
},
{
[RG_LANG_EN] = "RTC config",
[RG_LANG_FR] = "Congig RTC"
},
{
[RG_LANG_EN] = "Palette",
[RG_LANG_FR] = "Palette"
},
{
[RG_LANG_EN] = "RTC config",
[RG_LANG_FR] = "Congig RTC"
},
{
[RG_LANG_EN] = "SRAM autosave",
[RG_LANG_FR] = "Sauvegarde auto SRAM"
},
{
[RG_LANG_EN] = "Enable BIOS",
[RG_LANG_FR] = "Activer BIOS"
},
{
[RG_LANG_EN] = "Name",
[RG_LANG_FR] = "Nom"
},
{
[RG_LANG_EN] = "Artist",
[RG_LANG_FR] = "Artiste"
},
{
[RG_LANG_EN] = "Copyright",
[RG_LANG_FR] = "Copyright"
},
{
[RG_LANG_EN] = "Playing",
[RG_LANG_FR] = "Playing"
},
{
[RG_LANG_EN] = "Palette",
[RG_LANG_FR] = "Palette"
},
{
[RG_LANG_EN] = "Overscan",
[RG_LANG_FR] = "Overscan"
},
{
[RG_LANG_EN] = "Crop sides",
[RG_LANG_FR] = "Couper les cotes"
},
{
[RG_LANG_EN] = "Sprite limit",
[RG_LANG_FR] = "Limite de sprite"
},
{
[RG_LANG_EN] = "Overscan",
[RG_LANG_FR] = "Overscan"
},
{
[RG_LANG_EN] = "Palette",
[RG_LANG_FR] = "Palette"
},
{
[RG_LANG_EN] = "Profile",
[RG_LANG_FR] = "Profile"
},
{
[RG_LANG_EN] = "<profile name>",
[RG_LANG_FR] = "<nom du profil>"
},
{
[RG_LANG_EN] = "Controls",
[RG_LANG_FR] = "Controles"
},
{
[RG_LANG_EN] = "Audio enable",
[RG_LANG_FR] = "Activer audio"
},
{
[RG_LANG_EN] = "Audio filter",
[RG_LANG_FR] = "Filtre audio"
},
// rg_gui.c
{
[RG_LANG_EN] = "Folder is empty.",
[RG_LANG_FR] = "Le dossier est vide."
},
{
[RG_LANG_EN] = "No",
[RG_LANG_FR] = "Non"
},
{
[RG_LANG_EN] = "OK",
[RG_LANG_FR] = "OK"
},
{
[RG_LANG_EN] = "On",
[RG_LANG_FR] = "On"
},
{
[RG_LANG_EN] = "Off",
[RG_LANG_FR] = "Off"
},
{
[RG_LANG_EN] = "Horiz",
[RG_LANG_FR] = "Horiz"
},
{
[RG_LANG_EN] = "Vert",
[RG_LANG_FR] = "Vert "
},
{
[RG_LANG_EN] = "Both",
[RG_LANG_FR] = "Tout"
},
{
[RG_LANG_EN] = "Fit",
[RG_LANG_FR] = "Ajuster"
},
{
[RG_LANG_EN] = "Full ",
[RG_LANG_FR] = "Remplir "
},
{
[RG_LANG_EN] = "Zoom",
[RG_LANG_FR] = "Zoomer"
},
// Led options
{
[RG_LANG_EN] = "LED options",
[RG_LANG_FR] = "Options LED"
},
{
[RG_LANG_EN] = "System activity",
[RG_LANG_FR] = "Activite systeme"
},
{
[RG_LANG_EN] = "Disk activity",
[RG_LANG_FR] = "Activite stockage"
},
{
[RG_LANG_EN] = "Low battery",
[RG_LANG_FR] = "Battery basse"
},
{
[RG_LANG_EN] = "Default",
[RG_LANG_FR] = "Default"
},
{
[RG_LANG_EN] = "none",
[RG_LANG_FR] = "Aucun"
},
{
[RG_LANG_EN] = "<None>",
[RG_LANG_FR] = "<Aucun>"
},
// Wifi
{
[RG_LANG_EN] = "Not connected",
[RG_LANG_FR] = "Non connecte"
},
{
[RG_LANG_EN] = "Connecting...",
[RG_LANG_FR] = "Connection..."
},
{
[RG_LANG_EN] = "Disconnecting...",
[RG_LANG_FR] = "Disconnection..."
},
{
[RG_LANG_EN] = "(empty)",
[RG_LANG_FR] = "(vide)"
},
{
[RG_LANG_EN] = "Wi-Fi Profile",
[RG_LANG_FR] = "Profil Wi-Fi"
},
{
[RG_LANG_EN] = "Wi-Fi AP",
[RG_LANG_FR] = "Wi-Fi AP"
},
{
[RG_LANG_EN] = "Start access point?\n\nSSID: retro-go\nPassword: retro-go\n\nBrowse: http://192.168.4.1/",
[RG_LANG_FR] = "Demarrer point d'acces?\n\nSSID: retro-go\nPassword: retro-go\n\nAdresse: http://192.168.4.1/"
},
{
[RG_LANG_EN] = "Wi-Fi enable",
[RG_LANG_FR] = "Activer Wi-Fi"
},
{
[RG_LANG_EN] = "Wi-Fi access point",
[RG_LANG_FR] = "Point d'acces WiFi"
},
{
[RG_LANG_EN] = "Network",
[RG_LANG_FR] = "Reseau"
},
{
[RG_LANG_EN] = "IP address",
[RG_LANG_FR] = "Adresse IP"
},
{
[RG_LANG_EN] = "Wifi Options",
[RG_LANG_FR] = "Options Wifi"
},
// retro-go settings
{
[RG_LANG_EN] = "Brightness",
[RG_LANG_FR] = "Luminosite"
},
{
[RG_LANG_EN] = "Volume",
[RG_LANG_FR] = "Volume"
},
{
[RG_LANG_EN] = "Audio out",
[RG_LANG_FR] = "Sortie audio"
},
{
[RG_LANG_EN] = "Font type",
[RG_LANG_FR] = "Police"
},
{
[RG_LANG_EN] = "Theme",
[RG_LANG_FR] = "Theme"
},
{
[RG_LANG_EN] = "Show clock",
[RG_LANG_FR] = "Horloge"
},
{
[RG_LANG_EN] = "Timezone",
[RG_LANG_FR] = "Fuseau"
},
{
[RG_LANG_EN] = "Wi-Fi options",
[RG_LANG_FR] = "Options Wi-Fi"
},
// app dettings
{
[RG_LANG_EN] = "Scaling",
[RG_LANG_FR] = "Format"
},
{
[RG_LANG_EN] = "Factor",
[RG_LANG_FR] = "Factor"
},
{
[RG_LANG_EN] = "Filter",
[RG_LANG_FR] = "Filtre"
},
{
[RG_LANG_EN] = "Border",
[RG_LANG_FR] = "Bordure"
},
{
[RG_LANG_EN] = "Speed",
[RG_LANG_FR] = "Vitesse"
},
// about menu
{
[RG_LANG_EN] = "Version",
[RG_LANG_FR] = "Version"
},
{
[RG_LANG_EN] = "Date",
[RG_LANG_FR] = "Date"
},
{
[RG_LANG_EN] = "Target",
[RG_LANG_FR] = "Cible"
},
{
[RG_LANG_EN] = "Website",
[RG_LANG_FR] = "Site Web"
},
{
[RG_LANG_EN] = "Options ",
[RG_LANG_FR] = "Options"
},
{
[RG_LANG_EN] = "View credits",
[RG_LANG_FR] = "Credits"
},
{
[RG_LANG_EN] = "Debug menu",
[RG_LANG_FR] = "Menu debug"
},
{
[RG_LANG_EN] = "Reset settings",
[RG_LANG_FR] = "Reset parametres"
},
// save slot
{
[RG_LANG_EN] = "Slot 0",
[RG_LANG_FR] = "Emplacement 0"
},
{
[RG_LANG_EN] = "Slot 1",
[RG_LANG_FR] = "Emplacement 1"
},
{
[RG_LANG_EN] = "Slot 2",
[RG_LANG_FR] = "Emplacement 2"
},
{
[RG_LANG_EN] = "Slot 3",
[RG_LANG_FR] = "Emplacement 3"
},
// game menu
{
[RG_LANG_EN] = "Save & Continue",
[RG_LANG_FR] = "Sauver et continuer"
},
{
[RG_LANG_EN] = "Save & Quit",
[RG_LANG_FR] = "Sauver et quitter"
},
{
[RG_LANG_EN] = "Load game",
[RG_LANG_FR] = "Charger partie"
},
{
[RG_LANG_EN] = "Reset",
[RG_LANG_FR] = "Reset"
},
{
[RG_LANG_EN] = "Netplay",
[RG_LANG_FR] = "Netplay"
},
{
[RG_LANG_EN] = "About",
[RG_LANG_FR] = "Infos"
},
{
[RG_LANG_EN] = "Quit",
[RG_LANG_FR] = "Quitter"
},
{
[RG_LANG_EN] = "Soft reset",
[RG_LANG_FR] = "Soft reset"
},
{
[RG_LANG_EN] = "Hard reset",
[RG_LANG_FR] = "Hard reset"
},
{
[RG_LANG_EN] = "Reset Emulation?",
[RG_LANG_FR] = "Reset Emulation?"
},
{
[RG_LANG_EN] = "Save",
[RG_LANG_FR] = "Sauver"
},
{
[RG_LANG_EN] = "Load",
[RG_LANG_FR] = "Charger"
},
// end of rg_gui.c
// main.c
{
[RG_LANG_EN] = "Show",
[RG_LANG_FR] = "Montrer"
},
{
[RG_LANG_EN] = "Hide",
[RG_LANG_FR] = "Cacher"
},
{
[RG_LANG_EN] = "Tabs Visibility",
[RG_LANG_FR] = "Visibilitee onglets"
},
// scroll modes
{
[RG_LANG_EN] = "Center",
[RG_LANG_FR] = "centrer"
},
{
[RG_LANG_EN] = "Paging",
[RG_LANG_FR] = "Paging"
},
// start screen
{
[RG_LANG_EN] = "Auto",
[RG_LANG_FR] = "Auto"
},
{
[RG_LANG_EN] = "Carousel",
[RG_LANG_FR] = "Carousel"
},
{
[RG_LANG_EN] = "Browser",
[RG_LANG_FR] = "Browser"
},
// preview
{
[RG_LANG_EN] = "None",
[RG_LANG_FR] = "Aucun"
},
{
[RG_LANG_EN] = "Cover,Save",
[RG_LANG_FR] = "Cover,Save"
},
{
[RG_LANG_EN] = "Save,Cover",
[RG_LANG_FR] = "Save,Cover"
},
{
[RG_LANG_EN] = "Cover only",
[RG_LANG_FR] = "Cover only"
},
{
[RG_LANG_EN] = "Save only",
[RG_LANG_FR] = "Save only"
},
// startup app
{
[RG_LANG_EN] = "Last game",
[RG_LANG_FR] = "Dernier jeu"
},
{
[RG_LANG_EN] = "Launcher",
[RG_LANG_FR] = "Launcher"
},
// launcher options
{
[RG_LANG_EN] = "Launcher Options",
[RG_LANG_FR] = "Options du lanceur"
},
{
[RG_LANG_EN] = "Color theme",
[RG_LANG_FR] = "Couleurs"
},
{
[RG_LANG_EN] = "Preview",
[RG_LANG_FR] = "Apercu"
},
{
[RG_LANG_EN] = "Scroll mode",
[RG_LANG_FR] = "Mode defilement"
},
{
[RG_LANG_EN] = "Start screen",
[RG_LANG_FR] = "Ecran demarrage"
},
{
[RG_LANG_EN] = "Hide tabs",
[RG_LANG_FR] = "Cacher onglet"
},
{
[RG_LANG_EN] = "File server",
[RG_LANG_FR] = "Serveur fichier"
},
{
[RG_LANG_EN] = "Startup app",
[RG_LANG_FR] = "App demarrage"
},
{
[RG_LANG_EN] = "Build CRC cache",
[RG_LANG_FR] = "Build CRC cache"
},
{
[RG_LANG_EN] = "Check for updates",
[RG_LANG_FR] = "Check for updates"
},
{
[RG_LANG_EN] = "HTTP Server Busy...",
[RG_LANG_FR] = "Server Web ..."
},
{
[RG_LANG_EN] = "SD Card Error",
[RG_LANG_FR] = "Erreur carte SD"
},
{
[RG_LANG_EN] = "Storage mount failed.\nMake sure the card is FAT32.",
[RG_LANG_FR] = "Erreur montage SD.\nVerifiez que la carte est en FAT32."
},
// end of main.c
// applications.c
{
[RG_LANG_EN] = "Scanning %s %d/%d",
[RG_LANG_FR] = "Scan %s %d/%d"
},
// message when no rom
{
[RG_LANG_EN] = "Welcome to Retro-Go!",
[RG_LANG_FR] = "Bienvenue sur Retro-Go!"
},
{
[RG_LANG_EN] = "Place roms in folder: %s",
[RG_LANG_FR] = "Placer les ROMS dans le dossier: %s"
},
{
[RG_LANG_EN] = "With file extension: %s",
[RG_LANG_FR] = "Avec l'extension: %s"
},
{
[RG_LANG_EN] = "You can hide this tab in the menu",
[RG_LANG_FR] = "Vous pouvez cacher cet onglet dans le menu"
},
{
[RG_LANG_EN] = "You have no %s games",
[RG_LANG_FR] = "Vous n'avez pas de jeux %s"
},
{
[RG_LANG_EN] = "File not found",
[RG_LANG_FR] = "Fichier non present"
},
// rom options
{
[RG_LANG_EN] = "Name",
[RG_LANG_FR] = "Nom"
},
{
[RG_LANG_EN] = "Folder",
[RG_LANG_FR] = "Dossier"
},
{
[RG_LANG_EN] = "Size",
[RG_LANG_FR] = "Taille"
},
{
[RG_LANG_EN] = "CRC32",
[RG_LANG_FR] = "CRC32"
},
{
[RG_LANG_EN] = "Delete file",
[RG_LANG_FR] = "Supprimer fichier"
},
{
[RG_LANG_EN] = "Close",
[RG_LANG_FR] = "Fermer"
},
{
[RG_LANG_EN] = "File properties",
[RG_LANG_FR] = "Propriete"
},
{
[RG_LANG_EN] = "Delete selected file?",
[RG_LANG_FR] = "Supprimer fichier?"
},
// in-game menu
{
[RG_LANG_EN] = "Resume game",
[RG_LANG_FR] = "Reprendre partie"
},
{
[RG_LANG_EN] = "New game",
[RG_LANG_FR] = "Nouvelle partie"
},
{
[RG_LANG_EN] = "Del favorite",
[RG_LANG_FR] = "supp favori"
},
{
[RG_LANG_EN] = "Add favorite",
[RG_LANG_FR] = "Ajouter favori"
},
{
[RG_LANG_EN] = "Delete save",
[RG_LANG_FR] = "Supp sauvegarde"
},
{
[RG_LANG_EN] = "Properties",
[RG_LANG_FR] = "Proprietes"
},
{
[RG_LANG_EN] = "Resume",
[RG_LANG_FR] = "Reprendre"
},
{
[RG_LANG_EN] = "Delete save?",
[RG_LANG_FR] = "Supp sauvegarde?"
},
{
[RG_LANG_EN] = "Delete sram file?",
[RG_LANG_FR] = "Supp fichier SRAM?"
},
// end of applications.c
// rg_system.c
{
[RG_LANG_EN] = "App unresponsive... Hold MENU to quit!",
[RG_LANG_FR] = "Plantage... MENU pour quitter"
},
{
[RG_LANG_EN] = "Reset all settings",
[RG_LANG_FR] = "Reset parametres"
},
{
[RG_LANG_EN] = "Reboot to factory ",
[RG_LANG_FR] = "Redemarrer usine"
},
{
[RG_LANG_EN] = "Reboot to launcher",
[RG_LANG_FR] = "Relancer launcher"
},
{
[RG_LANG_EN] = "Recovery mode",
[RG_LANG_FR] = "Mode de recuperation"
},
{
[RG_LANG_EN] = "System Panic!",
[RG_LANG_FR] = "Plantage systeme!"
},
{
[RG_LANG_EN] = "Save failed",
[RG_LANG_FR] = "Erreur sauvegarde"
},
// end of rg_system.c
};

View File

@ -384,7 +384,7 @@ static rg_gui_event_t crop_select_cb(rg_gui_option_t *option, rg_gui_event_t eve
rg_settings_set_number(NS_APP, "Crop", CropPicture);
return RG_DIALOG_REDRAW;
}
strcpy(option->value, CropPicture ? "On" : "Off");
strcpy(option->value, CropPicture ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -395,7 +395,7 @@ static rg_gui_event_t input_select_cb(rg_gui_option_t *option, rg_gui_event_t ev
KeyboardEmulation = !KeyboardEmulation;
rg_settings_set_number(NS_APP, "Input", KeyboardEmulation);
}
strcpy(option->value, KeyboardEmulation ? "Keyboard" : "Joystick");
strcpy(option->value, KeyboardEmulation ? _("Keyboard") : _("Joystick"));
return RG_DIALOG_VOID;
}
@ -430,8 +430,8 @@ void app_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Input", "-", RG_DIALOG_FLAG_NORMAL, &input_select_cb},
{0, "Crop ", "-", RG_DIALOG_FLAG_NORMAL, &crop_select_cb},
{0, _("Input"), "-", RG_DIALOG_FLAG_NORMAL, &input_select_cb},
{0, _("Crop"), "-", RG_DIALOG_FLAG_NORMAL, &crop_select_cb},
// {0, "fMSX Menu", NULL, RG_DIALOG_FLAG_NORMAL, &fmsx_menu_cb},
RG_DIALOG_END,
};
@ -456,7 +456,7 @@ void app_main(void)
char message[512];
snprintf(message, 512, "File: %s\nYou can find it at:\n%s",
rg_relpath(pathbuf), "https://fms.komkon.org/fMSX/");
rg_gui_alert("BIOS file missing!", message);
rg_gui_alert(_("BIOS file missing!"), message);
}
}

View File

@ -115,7 +115,7 @@ static rg_gui_event_t yfm_update_cb(rg_gui_option_t *option, rg_gui_event_t even
yfm_enabled = !yfm_enabled;
rg_settings_set_number(NS_APP, SETTING_YFM_EMULATION, yfm_enabled);
}
strcpy(option->value, yfm_enabled ? "On " : "Off");
strcpy(option->value, yfm_enabled ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -127,7 +127,7 @@ static rg_gui_event_t sn76489_update_cb(rg_gui_option_t *option, rg_gui_event_t
sn76489_enabled = !sn76489_enabled;
rg_settings_set_number(NS_APP, SETTING_SN76489_EMULATION, sn76489_enabled);
}
strcpy(option->value, sn76489_enabled ? "On " : "Off");
strcpy(option->value, sn76489_enabled ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -139,7 +139,7 @@ static rg_gui_event_t z80_update_cb(rg_gui_option_t *option, rg_gui_event_t even
z80_enabled = !z80_enabled;
rg_settings_set_number(NS_APP, SETTING_Z80_EMULATION, z80_enabled);
}
strcpy(option->value, z80_enabled ? "On " : "Off");
strcpy(option->value, z80_enabled ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -199,9 +199,9 @@ void app_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "YM2612 audio ", "-", RG_DIALOG_FLAG_NORMAL, &yfm_update_cb},
{0, "SN76489 audio", "-", RG_DIALOG_FLAG_NORMAL, &sn76489_update_cb},
{0, "Z80 emulation", "-", RG_DIALOG_FLAG_NORMAL, &z80_update_cb},
{0, _("YM2612 audio "), "-", RG_DIALOG_FLAG_NORMAL, &yfm_update_cb},
{0, _("SN76489 audio"), "-", RG_DIALOG_FLAG_NORMAL, &sn76489_update_cb},
{0, _("Z80 emulation"), "-", RG_DIALOG_FLAG_NORMAL, &z80_update_cb},
RG_DIALOG_END
};

View File

@ -287,7 +287,7 @@ void crc_cache_prebuild(void)
{
retro_file_t *file = &app->files[j];
rg_gui_draw_message("Scanning %s %d/%d", app->short_name, j, app->files_count);
rg_gui_draw_message(_("Scanning %s %d/%d"), app->short_name, j, app->files_count);
// Give up on any button press to improve responsiveness
if (rg_input_read_gamepad())
@ -366,12 +366,12 @@ static void tab_refresh(tab_t *tab, const char *selected)
if (items_count == 0)
{
gui_resize_list(tab, 6);
sprintf(tab->listbox.items[0].text, "Welcome to Retro-Go!");
sprintf(tab->listbox.items[0].text, _("Welcome to Retro-Go!"));
sprintf(tab->listbox.items[1].text, " ");
sprintf(tab->listbox.items[2].text, "Place roms in folder: %s", rg_relpath(app->paths.roms));
sprintf(tab->listbox.items[3].text, "With file extension: %s", app->extensions);
sprintf(tab->listbox.items[2].text, _("Place roms in folder: %s"), rg_relpath(app->paths.roms));
sprintf(tab->listbox.items[3].text, _("With file extension: %s"), app->extensions);
sprintf(tab->listbox.items[4].text, " ");
sprintf(tab->listbox.items[5].text, "You can hide this tab in the menu");
sprintf(tab->listbox.items[5].text, _("You can hide this tab in the menu"));
tab->listbox.cursor = 4;
}
else if (selected)
@ -538,18 +538,18 @@ static void show_file_info(retro_file_t *file)
if (!info.exists)
{
rg_gui_alert("File not found", file->name);
rg_gui_alert(_("File not found"), file->name);
return;
}
rg_gui_option_t options[] = {
{0, "Name", (char *)file->name, 1, NULL},
{0, "Folder", (char *)file->folder, 1, NULL},
{0, "Size", filesize, 1, NULL},
{3, "CRC32", filecrc, 1, NULL},
{0, _("Name"), (char *)file->name, 1, NULL},
{0, _("Folder"), (char *)file->folder, 1, NULL},
{0, _("Size"), filesize, 1, NULL},
{3, _("CRC32"), filecrc, 1, NULL},
RG_DIALOG_SEPARATOR,
{5, "Delete file", NULL, 1, NULL},
{1, "Close", NULL, 1, NULL},
{5, _("Delete file"), NULL, 1, NULL},
{1, _("Close"), NULL, 1, NULL},
RG_DIALOG_END,
};
@ -560,13 +560,13 @@ static void show_file_info(retro_file_t *file)
if (file->checksum)
sprintf(filecrc, "%08X (%d)", (int)file->checksum, file->app->crc_offset);
switch (rg_gui_dialog("File properties", options, -1))
switch (rg_gui_dialog(_("File properties"), options, -1))
{
case 3:
application_get_file_crc32(file);
continue;
case 5:
if (rg_gui_confirm("Delete selected file?", 0, 0))
if (rg_gui_confirm(_("Delete selected file?"), 0, 0))
{
if (remove(get_file_path(file)) == 0)
{
@ -595,13 +595,13 @@ void application_show_file_menu(retro_file_t *file, bool advanced)
int slot = -1;
rg_gui_option_t choices[] = {
{0, "Resume game", NULL, has_save, NULL},
{1, "New game ", NULL, 1, NULL},
{0, _("Resume game"), NULL, has_save, NULL},
{1, _("New game"), NULL, 1, NULL},
RG_DIALOG_SEPARATOR,
{3, is_fav ? "Del favorite" : "Add favorite", NULL, 1, NULL},
{2, "Delete save", NULL, has_save || has_sram, NULL},
{3, is_fav ? _("Del favorite") : _("Add favorite"), NULL, 1, NULL},
{2, _("Delete save"), NULL, has_save || has_sram, NULL},
RG_DIALOG_SEPARATOR,
{4, "Properties", NULL, 1, NULL},
{4, _("Properties"), NULL, 1, NULL},
RG_DIALOG_END,
};
@ -609,7 +609,7 @@ void application_show_file_menu(retro_file_t *file, bool advanced)
switch (sel)
{
case 0:
if ((slot = rg_gui_savestate_menu("Resume", rom_path, 1)) == -1)
if ((slot = rg_gui_savestate_menu(_("Resume"), rom_path, 1)) == -1)
break;
/* fallthrough */
case 1:
@ -619,13 +619,13 @@ void application_show_file_menu(retro_file_t *file, bool advanced)
break;
case 2:
while ((slot = rg_gui_savestate_menu("Delete save?", rom_path, 0)) != -1)
while ((slot = rg_gui_savestate_menu(_("Delete save?"), rom_path, 0)) != -1)
{
remove(savestates->slots[slot].preview);
remove(savestates->slots[slot].file);
// FIXME: We should update the last slot used here
}
if (has_sram && rg_gui_confirm("Delete sram file?", 0, 0))
if (has_sram && rg_gui_confirm(_("Delete sram file?"), 0, 0))
{
remove(sram_path);
}

View File

@ -81,11 +81,11 @@ static void tab_refresh(book_t *book)
if (items_count == 0)
{
gui_resize_list(tab, 6);
sprintf(tab->listbox.items[0].text, "Welcome to Retro-Go!");
sprintf(tab->listbox.items[0].text, _("Welcome to Retro-Go!"));
sprintf(tab->listbox.items[1].text, " ");
sprintf(tab->listbox.items[2].text, "You have no %s games", book->name);
sprintf(tab->listbox.items[2].text, _("You have no %s games"), book->name);
sprintf(tab->listbox.items[3].text, " ");
sprintf(tab->listbox.items[4].text, "You can hide this tab in the menu");
sprintf(tab->listbox.items[4].text, _("You can hide this tab in the menu"));
tab->listbox.cursor = 3;
}
}

View File

@ -15,6 +15,7 @@ retro_gui_t gui;
#define SETTING_SELECTED_TAB "SelectedTab"
#define SETTING_START_SCREEN "StartScreen"
#define SETTING_STARTUP_MODE "StartupMode"
#define SETTING_LANGUAGE "Language"
#define SETTING_COLOR_THEME "ColorTheme"
#define SETTING_SHOW_PREVIEW "ShowPreview"
#define SETTING_SCROLL_MODE "ScrollMode"
@ -32,6 +33,7 @@ void gui_init(bool cold_boot)
gui = (retro_gui_t){
.selected_tab = rg_settings_get_number(NS_APP, SETTING_SELECTED_TAB, 0),
.startup_mode = rg_settings_get_number(NS_APP, SETTING_STARTUP_MODE, 0),
.language = rg_settings_get_number(NS_APP, SETTING_LANGUAGE, 0),
.color_theme = rg_settings_get_number(NS_APP, SETTING_COLOR_THEME, 0),
.start_screen = rg_settings_get_number(NS_APP, SETTING_START_SCREEN, START_SCREEN_AUTO),
.show_preview = rg_settings_get_number(NS_APP, SETTING_SHOW_PREVIEW, PREVIEW_MODE_SAVE_COVER),

View File

@ -121,6 +121,7 @@ typedef struct {
size_t tabs_count;
int selected_tab;
int startup_mode;
int language;
int browse;
int color_theme;
int start_screen;

View File

@ -26,7 +26,7 @@ static rg_gui_event_t toggle_tab_cb(rg_gui_option_t *option, rg_gui_event_t even
{
tab->enabled = !tab->enabled;
}
strcpy(option->value, tab->enabled ? "Show" : "Hide");
strcpy(option->value, tab->enabled ? _("Show") : _("Hide"));
return RG_DIALOG_VOID;
}
@ -41,14 +41,14 @@ static rg_gui_event_t toggle_tabs_cb(rg_gui_option_t *option, rg_gui_event_t eve
*opt++ = (rg_gui_option_t){i, gui.tabs[i]->name, "...", 1, &toggle_tab_cb};
*opt++ = (rg_gui_option_t)RG_DIALOG_END;
rg_gui_dialog("Tabs Visibility", options, 0);
rg_gui_dialog(_("Tabs Visibility"), options, 0);
}
return RG_DIALOG_VOID;
}
static rg_gui_event_t scroll_mode_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
const char *modes[SCROLL_MODE_COUNT] = {"Center", "Paging"};
const char *modes[SCROLL_MODE_COUNT] = {_("Center"), _("Paging")};
const int max = SCROLL_MODE_COUNT - 1;
if (event == RG_DIALOG_PREV && --gui.scroll_mode < 0)
@ -67,7 +67,7 @@ static rg_gui_event_t scroll_mode_cb(rg_gui_option_t *option, rg_gui_event_t eve
static rg_gui_event_t start_screen_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
const char *modes[START_SCREEN_COUNT] = {"Auto", "Carousel", "Browser"};
const char *modes[START_SCREEN_COUNT] = {_("Auto"), _("Carousel"), _("Browser")};
const int max = START_SCREEN_COUNT - 1;
if (event == RG_DIALOG_PREV && --gui.start_screen < 0)
@ -83,7 +83,7 @@ static rg_gui_event_t start_screen_cb(rg_gui_option_t *option, rg_gui_event_t ev
static rg_gui_event_t show_preview_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
const char *modes[] = {"None ", "Cover,Save", "Save,Cover", "Cover only", "Save only "};
const char *modes[] = {_("None"), _("Cover,Save"), _("Save,Cover"), _("Cover only"), _("Save only")};
const int max = PREVIEW_MODE_COUNT - 1;
if (event == RG_DIALOG_PREV && --gui.show_preview < 0)
@ -131,7 +131,7 @@ static rg_gui_event_t color_theme_cb(rg_gui_option_t *option, rg_gui_event_t eve
static rg_gui_event_t startup_app_cb(rg_gui_option_t *option, rg_gui_event_t event)
{
const char *modes[] = {"Last game", "Launcher"};
const char *modes[] = {_("Last game"), _("Launcher")};
int max = 1;
if (event == RG_DIALOG_PREV && --gui.startup_mode < 0)
@ -170,7 +170,7 @@ static rg_gui_event_t webui_switch_cb(rg_gui_option_t *option, rg_gui_event_t ev
webui_start();
rg_settings_set_number(NS_APP, SETTING_WEBUI, enabled);
}
strcpy(option->value, enabled ? "On " : "Off");
strcpy(option->value, enabled ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
#endif
@ -180,19 +180,19 @@ static rg_gui_event_t launcher_options_cb(rg_gui_option_t *option, rg_gui_event_
if (event == RG_DIALOG_ENTER)
{
const rg_gui_option_t options[] = {
{0, "Color theme ", "-", RG_DIALOG_FLAG_NORMAL, &color_theme_cb},
{0, "Preview ", "-", RG_DIALOG_FLAG_NORMAL, &show_preview_cb},
{0, "Scroll mode ", "-", RG_DIALOG_FLAG_NORMAL, &scroll_mode_cb},
{0, "Start screen", "-", RG_DIALOG_FLAG_NORMAL, &start_screen_cb},
{0, "Hide tabs ", "-", RG_DIALOG_FLAG_NORMAL, &toggle_tabs_cb},
{0, _("Color theme"), "-", RG_DIALOG_FLAG_NORMAL, &color_theme_cb},
{0, _("Preview"), "-", RG_DIALOG_FLAG_NORMAL, &show_preview_cb},
{0, _("Scroll mode"), "-", RG_DIALOG_FLAG_NORMAL, &scroll_mode_cb},
{0, _("Start screen"), "-", RG_DIALOG_FLAG_NORMAL, &start_screen_cb},
{0, _("Hide tabs"), "-", RG_DIALOG_FLAG_NORMAL, &toggle_tabs_cb},
#ifdef RG_ENABLE_NETWORKING
{0, "File server ", "-", RG_DIALOG_FLAG_NORMAL, &webui_switch_cb},
{0, _("File server"), "-", RG_DIALOG_FLAG_NORMAL, &webui_switch_cb},
#endif
{0, "Startup app ", "-", RG_DIALOG_FLAG_NORMAL, &startup_app_cb},
{0, _("Startup app"), "-", RG_DIALOG_FLAG_NORMAL, &startup_app_cb},
RG_DIALOG_END,
};
gui_redraw(); // clear main menu
rg_gui_dialog("Launcher Options", options, 0);
rg_gui_dialog(_("Launcher Options"), options, 0);
}
return RG_DIALOG_VOID;
}
@ -213,9 +213,9 @@ static rg_gui_event_t prebuild_cache_cb(rg_gui_option_t *option, rg_gui_event_t
static void show_about_menu(void)
{
const rg_gui_option_t options[] = {
{0, "Build CRC cache", NULL, RG_DIALOG_FLAG_NORMAL, &prebuild_cache_cb},
{0, _("Build CRC cache"), NULL, RG_DIALOG_FLAG_NORMAL, &prebuild_cache_cb},
#ifdef RG_ENABLE_NETWORKING
{0, "Check for updates", NULL, RG_DIALOG_FLAG_NORMAL, &updater_cb},
{0, _("Check for updates"), NULL, RG_DIALOG_FLAG_NORMAL, &updater_cb},
#endif
RG_DIALOG_END,
};
@ -253,7 +253,7 @@ static void retro_loop(void)
// It's also risky to let the user do file accesses at the same time (thread safety, SPI, etc)...
if (gui.http_lock)
{
rg_gui_draw_message("HTTP Server Busy...");
rg_gui_draw_message(_("HTTP Server Busy..."));
redraw_pending = true;
rg_task_delay(100);
continue;
@ -446,7 +446,7 @@ void app_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Launcher options", NULL, RG_DIALOG_FLAG_NORMAL, &launcher_options_cb},
{0, _("Launcher options"), NULL, RG_DIALOG_FLAG_NORMAL, &launcher_options_cb},
RG_DIALOG_END,
};
@ -457,7 +457,7 @@ void app_main(void)
if (!rg_storage_ready())
{
rg_display_clear(C_SKY_BLUE);
rg_gui_alert("SD Card Error", "Storage mount failed.\nMake sure the card is FAT32.");
rg_gui_alert(_("SD Card Error"), _("Storage mount failed.\nMake sure the card is FAT32."));
}
else
{

View File

@ -135,8 +135,8 @@ static rg_gui_event_t view_release_cb(rg_gui_option_t *option, rg_gui_event_t ev
rg_gui_option_t options[release->assets_count + 4];
rg_gui_option_t *opt = options;
*opt++ = (rg_gui_option_t){0, "Date", release->date, -1, NULL};
*opt++ = (rg_gui_option_t){0, "Files:", NULL, -1, NULL};
*opt++ = (rg_gui_option_t){0, _("Date"), release->date, -1, NULL};
*opt++ = (rg_gui_option_t){0, _("Files:"), NULL, -1, NULL};
for (int i = 0; i < release->assets_count; i++)
*opt++ = (rg_gui_option_t){i, release->assets[i].name, NULL, 1, NULL};
@ -150,7 +150,7 @@ static rg_gui_event_t view_release_cb(rg_gui_option_t *option, rg_gui_event_t ev
gui_redraw();
if (download_file(release->assets[sel].url, dest_path))
{
if (rg_gui_confirm("Download complete!", "Reboot to flash?", true))
if (rg_gui_confirm(_("Download complete!"), _("Reboot to flash?"), true))
rg_system_switch_app(RG_APP_UPDATER, NULL, dest_path, 0);
}
}
@ -212,11 +212,11 @@ void updater_show_dialog(void)
*opt++ = (rg_gui_option_t){(intptr_t)&releases[i], releases[i].name, NULL, 1, &view_release_cb};
*opt++ = (rg_gui_option_t)RG_DIALOG_END;
rg_gui_dialog("Available Releases", options, 0);
rg_gui_dialog(_("Available Releases"), options, 0);
}
else
{
rg_gui_alert("Available Releases", "Received empty list!");
rg_gui_alert(_("Available Releases"), _("Received empty list!"));
}
for (int i = 0; i < releases_count; ++i)

View File

@ -534,7 +534,7 @@ void app_main()
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Gamma Boost", "-", RG_DIALOG_FLAG_NORMAL, &gamma_update_cb},
{0, _("Gamma Boost"), "-", RG_DIALOG_FLAG_NORMAL, &gamma_update_cb},
RG_DIALOG_END
};

View File

@ -138,7 +138,7 @@ static rg_gui_event_t sram_autosave_cb(rg_gui_option_t *option, rg_gui_event_t e
rg_settings_set_number(NS_APP, SETTING_SAVESRAM, autoSaveSRAM);
}
if (autoSaveSRAM == 0) strcpy(option->value, "Off ");
if (autoSaveSRAM == 0) strcpy(option->value, _("Off"));
else sprintf(option->value, "%3ds", autoSaveSRAM);
return RG_DIALOG_VOID;
@ -151,7 +151,7 @@ static rg_gui_event_t enable_bios_cb(rg_gui_option_t *option, rg_gui_event_t eve
loadBIOSFile = !loadBIOSFile;
rg_settings_set_number(NS_APP, SETTING_LOADBIOS, loadBIOSFile);
}
strcpy(option->value, loadBIOSFile ? "Yes" : "No");
strcpy(option->value, loadBIOSFile ? _("Yes") : _("No"));
return RG_DIALOG_VOID;
}
@ -186,7 +186,7 @@ static rg_gui_event_t rtc_t_update_cb(rg_gui_option_t *option, rg_gui_event_t ev
useSystemTime = !useSystemTime;
rg_settings_set_number(NS_APP, SETTING_SYSTIME, useSystemTime);
}
strcpy(option->value, useSystemTime ? "Yes" : "No ");
strcpy(option->value, useSystemTime ? _("Yes") : _("No"));
}
gnuboy_set_time(d, h, m, s);
@ -200,14 +200,14 @@ static rg_gui_event_t rtc_update_cb(rg_gui_option_t *option, rg_gui_event_t even
{
if (event == RG_DIALOG_ENTER) {
const rg_gui_option_t choices[] = {
{'d', "Day ", "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'h', "Hour", "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'m', "Min ", "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'s', "Sec ", "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'x', "Sync", "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'d', _("Day"), "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'h', _("Hour"), "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'m', _("Min"), "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'s', _("Sec"), "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
{'x', _("Sync"), "-", RG_DIALOG_FLAG_NORMAL, &rtc_t_update_cb},
RG_DIALOG_END
};
rg_gui_dialog("RTC config", choices, 0);
rg_gui_dialog(_("RTC config"), choices, 0);
}
int h, m;
gnuboy_get_time(NULL, &h, &m, NULL);
@ -241,10 +241,10 @@ void gbc_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Palette ", "-", RG_DIALOG_FLAG_NORMAL, &palette_update_cb},
{0, "RTC config ", "-", RG_DIALOG_FLAG_NORMAL, &rtc_update_cb},
{0, "SRAM autosave", "-", RG_DIALOG_FLAG_NORMAL, &sram_autosave_cb},
{0, "Enable BIOS ", "-", RG_DIALOG_FLAG_NORMAL, &enable_bios_cb},
{0, _("Palette"), "-", RG_DIALOG_FLAG_NORMAL, &palette_update_cb},
{0, _("RTC config"), "-", RG_DIALOG_FLAG_NORMAL, &rtc_update_cb},
{0, _("SRAM autosave"), "-", RG_DIALOG_FLAG_NORMAL, &sram_autosave_cb},
{0, _("Enable BIOS"), "-", RG_DIALOG_FLAG_NORMAL, &enable_bios_cb},
RG_DIALOG_END
};

View File

@ -119,10 +119,10 @@ static rg_gui_event_t rotation_cb(rg_gui_option_t *option, rg_gui_event_t event)
return RG_DIALOG_REDRAW;
}
strcpy(option->value, "Off ");
if (rotation == RG_DISPLAY_ROTATION_AUTO) strcpy(option->value, "Auto ");
if (rotation == RG_DISPLAY_ROTATION_LEFT) strcpy(option->value, "Left ");
if (rotation == RG_DISPLAY_ROTATION_RIGHT) strcpy(option->value, "Right");
strcpy(option->value, _("Off"));
if (rotation == RG_DISPLAY_ROTATION_AUTO) strcpy(option->value, _("Auto"));
if (rotation == RG_DISPLAY_ROTATION_LEFT) strcpy(option->value, _("Left"));
if (rotation == RG_DISPLAY_ROTATION_RIGHT) strcpy(option->value, _("Right"));
return RG_DIALOG_VOID;
}
@ -190,7 +190,7 @@ extern "C" void lynx_main(void)
.memWrite = NULL,
};
const rg_gui_option_t options[] = {
{0, "Rotation", (char *)"-", RG_DIALOG_FLAG_NORMAL, &rotation_cb},
{0, _("Rotation"), (char *)"-", RG_DIALOG_FLAG_NORMAL, &rotation_cb},
RG_DIALOG_END
};

View File

@ -79,7 +79,7 @@ static rg_gui_event_t sprite_limit_cb(rg_gui_option_t *option, rg_gui_event_t ev
ppu_setopt(PPU_LIMIT_SPRITES, spritelimit);
}
strcpy(option->value, spritelimit ? "On " : "Off");
strcpy(option->value, spritelimit ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -93,7 +93,7 @@ static rg_gui_event_t overscan_update_cb(rg_gui_option_t *option, rg_gui_event_t
return RG_DIALOG_REDRAW;
}
strcpy(option->value, overscan ? "Auto" : "Off ");
strcpy(option->value, overscan ? _("Auto") : _("Off"));
return RG_DIALOG_VOID;
}
@ -113,9 +113,9 @@ static rg_gui_event_t autocrop_update_cb(rg_gui_option_t *option, rg_gui_event_t
return RG_DIALOG_REDRAW;
}
if (val == 0) strcpy(option->value, "Never ");
if (val == 1) strcpy(option->value, "Auto ");
if (val == 2) strcpy(option->value, "Always");
if (val == 0) strcpy(option->value, _("Never"));
if (val == 1) strcpy(option->value, _("Auto"));
if (val == 2) strcpy(option->value, _("Always"));
return RG_DIALOG_VOID;
}
@ -136,12 +136,12 @@ static rg_gui_event_t palette_update_cb(rg_gui_option_t *option, rg_gui_event_t
return RG_DIALOG_REDRAW;
}
if (pal == NES_PALETTE_NOFRENDO) strcpy(option->value, "Default ");
if (pal == NES_PALETTE_COMPOSITE) strcpy(option->value, "Composite ");
if (pal == NES_PALETTE_NESCLASSIC) strcpy(option->value, "NES Classic");
if (pal == NES_PALETTE_NTSC) strcpy(option->value, "NTSC ");
if (pal == NES_PALETTE_PVM) strcpy(option->value, "PVM ");
if (pal == NES_PALETTE_SMOOTH) strcpy(option->value, "Smooth ");
if (pal == NES_PALETTE_NOFRENDO) strcpy(option->value, _("Default"));
if (pal == NES_PALETTE_COMPOSITE) strcpy(option->value, _("Composite"));
if (pal == NES_PALETTE_NESCLASSIC) strcpy(option->value, _("NES Classic"));
if (pal == NES_PALETTE_NTSC) strcpy(option->value, _("NTSC"));
if (pal == NES_PALETTE_PVM) strcpy(option->value, _("PVM"));
if (pal == NES_PALETTE_SMOOTH) strcpy(option->value, _("Smooth"));
return RG_DIALOG_VOID;
}
@ -167,10 +167,10 @@ static void nsf_draw_overlay(void)
char song[32];
const nsfheader_t *header = (nsfheader_t *)nes->cart->data_ptr;
const rg_gui_option_t options[] = {
{0, "Name ", (char*)header->name, RG_DIALOG_FLAG_NORMAL, NULL},
{0, "Artist ", (char*)header->artist, RG_DIALOG_FLAG_NORMAL, NULL},
{0, "Copyright ", (char*)header->copyright, RG_DIALOG_FLAG_NORMAL, NULL},
{0, "Playing ", (char*)song, RG_DIALOG_FLAG_NORMAL, NULL},
{0, _("Name"), (char*)header->name, RG_DIALOG_FLAG_NORMAL, NULL},
{0, _("Artist"), (char*)header->artist, RG_DIALOG_FLAG_NORMAL, NULL},
{0, _("Copyright"), (char*)header->copyright, RG_DIALOG_FLAG_NORMAL, NULL},
{0, _("Playing"), (char*)song, RG_DIALOG_FLAG_NORMAL, NULL},
RG_DIALOG_END,
};
snprintf(song, sizeof(song), "%d / %d", nsf_current_song, header->total_songs);
@ -188,10 +188,10 @@ void nes_main(void)
.screenshot = &screenshot_handler,
};
const rg_gui_option_t options[] = {
{0, "Palette ", "-", RG_DIALOG_FLAG_NORMAL, &palette_update_cb},
{0, "Overscan ", "-", RG_DIALOG_FLAG_NORMAL, &overscan_update_cb},
{0, "Crop sides ", "-", RG_DIALOG_FLAG_NORMAL, &autocrop_update_cb},
{0, "Sprite limit", "-", RG_DIALOG_FLAG_NORMAL, &sprite_limit_cb},
{0, _("Palette"), "-", RG_DIALOG_FLAG_NORMAL, &palette_update_cb},
{0, _("Overscan"), "-", RG_DIALOG_FLAG_NORMAL, &overscan_update_cb},
{0, _("Crop sides"), "-", RG_DIALOG_FLAG_NORMAL, &autocrop_update_cb},
{0, _("Sprite limit"), "-", RG_DIALOG_FLAG_NORMAL, &sprite_limit_cb},
RG_DIALOG_END
};

View File

@ -34,7 +34,7 @@ static rg_gui_event_t overscan_update_cb(rg_gui_option_t *option, rg_gui_event_t
return RG_DIALOG_REDRAW;
}
strcpy(option->value, overscan ? "On " : "Off");
strcpy(option->value, overscan ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -189,7 +189,7 @@ void pce_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Overscan", "-", RG_DIALOG_FLAG_NORMAL, &overscan_update_cb},
{0, _("Overscan"), "-", RG_DIALOG_FLAG_NORMAL, &overscan_update_cb},
RG_DIALOG_END
};

View File

@ -102,7 +102,7 @@ void sms_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Palette ", "-", RG_DIALOG_FLAG_NORMAL, &palette_update_cb},
{0, _("Palette"), "-", RG_DIALOG_FLAG_NORMAL, &palette_update_cb},
RG_DIALOG_END
};
@ -214,7 +214,7 @@ void sms_main(void)
if (joystick & RG_KEY_START)
{
rg_gui_draw_text(RG_GUI_CENTER, RG_GUI_CENTER, 0, "To start, try: 1 or * or #", C_YELLOW, C_BLACK, RG_TEXT_BIGGER);
rg_gui_draw_text(RG_GUI_CENTER, RG_GUI_CENTER, 0, _("To start, try: 1 or * or #"), C_YELLOW, C_BLACK, RG_TEXT_BIGGER);
rg_audio_set_mute(true);
int key = rg_input_read_keyboard(&coleco_keyboard);
rg_audio_set_mute(false);

View File

@ -122,7 +122,7 @@ static rg_gui_event_t apu_toggle_cb(rg_gui_option_t *option, rg_gui_event_t even
rg_settings_set_number(NS_APP, SETTING_APU_EMULATION, apu_enabled);
}
strcpy(option->value, apu_enabled ? "On " : "Off");
strcpy(option->value, apu_enabled ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -132,7 +132,7 @@ static rg_gui_event_t lowpass_filter_cb(rg_gui_option_t *option, rg_gui_event_t
if (event == RG_DIALOG_PREV || event == RG_DIALOG_NEXT)
lowpass_filter = !lowpass_filter;
strcpy(option->value, lowpass_filter ? "On" : "Off");
strcpy(option->value, lowpass_filter ? _("On") : _("Off"));
return RG_DIALOG_VOID;
}
@ -188,7 +188,7 @@ static rg_gui_event_t menu_keymap_cb(rg_gui_option_t *option, rg_gui_event_t eve
if (event == RG_DIALOG_ENTER)
{
const rg_gui_option_t options[20] = {
{-1, "Profile", "<profile name>", RG_DIALOG_FLAG_NORMAL, &change_keymap_cb},
{-1, _("Profile"), _("<profile name>"), RG_DIALOG_FLAG_NORMAL, &change_keymap_cb},
{-2, "", NULL, RG_DIALOG_FLAG_MESSAGE, NULL},
{-3, "snes9x ", "handheld", RG_DIALOG_FLAG_MESSAGE, NULL},
{0, "-", "-", RG_DIALOG_FLAG_HIDDEN, &change_keymap_cb},
@ -209,7 +209,7 @@ static rg_gui_event_t menu_keymap_cb(rg_gui_option_t *option, rg_gui_event_t eve
{15, "-", "-", RG_DIALOG_FLAG_HIDDEN, &change_keymap_cb},
RG_DIALOG_END,
};
rg_gui_dialog("Controls", options, 0);
rg_gui_dialog(_("Controls"), options, 0);
return RG_DIALOG_REDRAW;
}
@ -292,9 +292,9 @@ void snes_main(void)
.event = &event_handler,
};
const rg_gui_option_t options[] = {
{0, "Audio enable", "-", RG_DIALOG_FLAG_NORMAL, &apu_toggle_cb},
{0, "Audio filter", "-", RG_DIALOG_FLAG_NORMAL, &lowpass_filter_cb},
{0, "Controls ", "-", RG_DIALOG_FLAG_NORMAL, &menu_keymap_cb},
{0, _("Audio enable"), "-", RG_DIALOG_FLAG_NORMAL, &apu_toggle_cb},
{0, _("Audio filter"), "-", RG_DIALOG_FLAG_NORMAL, &lowpass_filter_cb},
{0, _("Controls"), "-", RG_DIALOG_FLAG_NORMAL, &menu_keymap_cb},
RG_DIALOG_END,
};
app = rg_system_reinit(AUDIO_SAMPLE_RATE, &handlers, options);

91
tools/rg_locate_str.py Normal file
View File

@ -0,0 +1,91 @@
import os
def scan_folder_for_strings(folder_path):
# List to store found strings in this file
file_strings = []
# Walk through the directory and subdirectories
for dirpath, _, filenames in os.walk(folder_path):
for filename in filenames:
file_path = os.path.join(dirpath, filename)
if file_path.endswith(".c"): # scanning all .c files
with open(file_path, 'r', encoding='utf-8') as file:
content = file.readlines()
# Search for the _(" pattern in each line
for line in content:
start = 0
while start < len(line):
# Find the occurrence of _(" in the line
start = line.find('_("', start)
if start == -1:
break # No more occurrences in this line
# Find the closing ")
end = line.find('")', start + 3) # search after _(
if end != -1:
# Extract the string between _(" and ")
extracted_string = line[start + 3:end]
file_strings.append(extracted_string)
start = end + 2 # Move past the last found string
else:
# If no closing, break out of loop to avoid infinite loop
break
return file_strings
def scan_file_for_msg_strings(file_path):
found_strings = []
try:
# Open the file and read it line by line
with open(file_path, 'r', encoding='utf-8') as file:
content = file.readlines()
# Search for the .msg = "pattern" in each line
for line in content:
start = 0
while start < len(line):
# Find the occurrence of .msg =
start = line.find('[RG_LANG_EN] = "', start)
if start == -1:
break # No more occurrences in this line
# Find the closing "
start_quote = start + len('[RG_LANG_EN] = "')
end_quote = line.find('"', start_quote)
if end_quote != -1:
# Extract the string between " and "
extracted_string = line[start_quote:end_quote]
found_strings.append(extracted_string)
start = end_quote + 1 # Move past the last found string
else:
# If no closing ", break out of the loop
break
except FileNotFoundError:
print(f"The file '{file_path}' does not exist.")
return found_strings
# Scan the project's folders for strings to translate _("string")
found_strings_in_files = scan_folder_for_strings(os.getcwd())
# removing any dupicates :
found_strings_in_files = list(dict.fromkeys(found_strings_in_files))
# Scan the file 'retro-go/localization.c'
translated = scan_file_for_msg_strings('components/retro-go/translations.h')
file = open("missing_translation.txt", "w")
for string in found_strings_in_files:
if string not in translated:
print("missing translation", '"'+string+'"')
file.write('{\n\t[RG_LANG_EN] = "'+string+'",\n\t[RG_LANG_FR] = \"\",\n},\n')
# file output :
#{
# [RG_LANG_EN] = "missing string",
# [RG_LANG_FR] = "",
#},
file.close()