diff --git a/LOCALIZATION.md b/LOCALIZATION.md new file mode 100644 index 000000000..87af1566c --- /dev/null +++ b/LOCALIZATION.md @@ -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 diff --git a/components/retro-go/libs/netplay/rg_netplay.c b/components/retro-go/libs/netplay/rg_netplay.c index 19f01ae6b..7fc943721 100644 --- a/components/retro-go/libs/netplay/rg_netplay.c +++ b/components/retro-go/libs/netplay/rg_netplay.c @@ -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) diff --git a/components/retro-go/rg_gui.c b/components/retro-go/rg_gui.c index 4fadddf50..96db0fdaf 100644 --- a/components/retro-go/rg_gui.c +++ b/components/retro-go/rg_gui.c @@ -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, "", NULL, RG_DIALOG_FLAG_NORMAL, NULL}; + options.options[options.count++] = (rg_gui_option_t){0, _(""), 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) diff --git a/components/retro-go/rg_gui.h b/components/retro-go/rg_gui.h index 168f25d0d..4e4760f35 100644 --- a/components/retro-go/rg_gui.h +++ b/components/retro-go/rg_gui.h @@ -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); diff --git a/components/retro-go/rg_localization.c b/components/retro-go/rg_localization.c new file mode 100644 index 000000000..ddc50f6f9 --- /dev/null +++ b/components/retro-go/rg_localization.c @@ -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]; +} diff --git a/components/retro-go/rg_localization.h b/components/retro-go/rg_localization.h new file mode 100644 index 000000000..b4c74c25a --- /dev/null +++ b/components/retro-go/rg_localization.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#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); diff --git a/components/retro-go/rg_system.c b/components/retro-go/rg_system.c index 40a47bb4b..9dbf59b76 100644 --- a/components/retro-go/rg_system.c +++ b/components/retro-go/rg_system.c @@ -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(); } diff --git a/components/retro-go/rg_system.h b/components/retro-go/rg_system.h index 0064682a0..8dacd93e3 100644 --- a/components/retro-go/rg_system.h +++ b/components/retro-go/rg_system.h @@ -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" diff --git a/components/retro-go/translations.h b/components/retro-go/translations.h new file mode 100644 index 000000000..d4d0afac5 --- /dev/null +++ b/components/retro-go/translations.h @@ -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] = "", + [RG_LANG_FR] = "" + }, + { + [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] = "", + [RG_LANG_FR] = "" + }, + + // 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 +}; diff --git a/fmsx/main/main.c b/fmsx/main/main.c index e1478e29e..7c82b5ca8 100644 --- a/fmsx/main/main.c +++ b/fmsx/main/main.c @@ -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); } } diff --git a/gwenesis/main/main.c b/gwenesis/main/main.c index 6ecb3223b..5a38f2d3e 100644 --- a/gwenesis/main/main.c +++ b/gwenesis/main/main.c @@ -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 }; diff --git a/launcher/main/applications.c b/launcher/main/applications.c index 48935f98b..8a0200e04 100644 --- a/launcher/main/applications.c +++ b/launcher/main/applications.c @@ -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); } diff --git a/launcher/main/bookmarks.c b/launcher/main/bookmarks.c index e4184c4e7..1863062c8 100644 --- a/launcher/main/bookmarks.c +++ b/launcher/main/bookmarks.c @@ -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; } } diff --git a/launcher/main/gui.c b/launcher/main/gui.c index 955678891..9b05e5b53 100644 --- a/launcher/main/gui.c +++ b/launcher/main/gui.c @@ -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), diff --git a/launcher/main/gui.h b/launcher/main/gui.h index b6bd77885..f0fbcdfeb 100644 --- a/launcher/main/gui.h +++ b/launcher/main/gui.h @@ -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; diff --git a/launcher/main/main.c b/launcher/main/main.c index 799e29130..7b2b458a0 100644 --- a/launcher/main/main.c +++ b/launcher/main/main.c @@ -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 { diff --git a/launcher/main/updater.c b/launcher/main/updater.c index bef41834b..b8258c267 100644 --- a/launcher/main/updater.c +++ b/launcher/main/updater.c @@ -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) diff --git a/prboom-go/main/main.c b/prboom-go/main/main.c index cfadddf63..659f4b48a 100644 --- a/prboom-go/main/main.c +++ b/prboom-go/main/main.c @@ -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 }; diff --git a/retro-core/main/main_gbc.c b/retro-core/main/main_gbc.c index d06527481..4fee00419 100644 --- a/retro-core/main/main_gbc.c +++ b/retro-core/main/main_gbc.c @@ -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 }; diff --git a/retro-core/main/main_lynx.cpp b/retro-core/main/main_lynx.cpp index 29a95c72e..2b13c4a7b 100644 --- a/retro-core/main/main_lynx.cpp +++ b/retro-core/main/main_lynx.cpp @@ -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 }; diff --git a/retro-core/main/main_nes.c b/retro-core/main/main_nes.c index 060cc1d22..96d1bcc62 100644 --- a/retro-core/main/main_nes.c +++ b/retro-core/main/main_nes.c @@ -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 }; diff --git a/retro-core/main/main_pce.c b/retro-core/main/main_pce.c index c78f6485c..49142c5db 100644 --- a/retro-core/main/main_pce.c +++ b/retro-core/main/main_pce.c @@ -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 }; diff --git a/retro-core/main/main_sms.c b/retro-core/main/main_sms.c index da57f4e86..d4714e178 100644 --- a/retro-core/main/main_sms.c +++ b/retro-core/main/main_sms.c @@ -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); diff --git a/retro-core/main/main_snes.c b/retro-core/main/main_snes.c index 6bc411c8b..fad7794ed 100644 --- a/retro-core/main/main_snes.c +++ b/retro-core/main/main_snes.c @@ -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", "", RG_DIALOG_FLAG_NORMAL, &change_keymap_cb}, + {-1, _("Profile"), _(""), 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); diff --git a/tools/rg_locate_str.py b/tools/rg_locate_str.py new file mode 100644 index 000000000..80a4aa132 --- /dev/null +++ b/tools/rg_locate_str.py @@ -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() \ No newline at end of file