diff --git a/gfx/drivers_font_renderer/bitmapfont_10x10.c b/gfx/drivers_font_renderer/bitmapfont_10x10.c
index 0d44faa44f..d8d9a140c8 100644
--- a/gfx/drivers_font_renderer/bitmapfont_10x10.c
+++ b/gfx/drivers_font_renderer/bitmapfont_10x10.c
@@ -54,6 +54,11 @@
#define FONT_10X10_GLYPH_MIN_KOR 0xAC00
#define FONT_10X10_GLYPH_MAX_KOR 0xD7A3
+#define FONT_10X10_FILE_RUS "bitmap10x10_rus.bin"
+#define FONT_10X10_SIZE_RUS 1248
+#define FONT_10X10_GLYPH_MIN_RUS 0x400
+#define FONT_10X10_GLYPH_MAX_RUS 0x45F
+
#define FONT_10X10_OFFSET(x) ((x) * ((FONT_10X10_HEIGHT * FONT_10X10_WIDTH + 7) / 8))
/* Loads a font of the specified language
@@ -107,6 +112,12 @@ bitmapfont_lut_t *bitmapfont_10x10_load(unsigned language)
glyph_min = FONT_10X10_GLYPH_MIN_KOR;
glyph_max = FONT_10X10_GLYPH_MAX_KOR;
break;
+ case RETRO_LANGUAGE_RUSSIAN:
+ font_file = FONT_10X10_FILE_RUS;
+ font_size = FONT_10X10_SIZE_RUS;
+ glyph_min = FONT_10X10_GLYPH_MIN_RUS;
+ glyph_max = FONT_10X10_GLYPH_MAX_RUS;
+ break;
default:
break;
}
diff --git a/intl/msg_hash_ru.c b/intl/msg_hash_ru.c
index 8ceb3cf9c1..9ba66acba5 100644
--- a/intl/msg_hash_ru.c
+++ b/intl/msg_hash_ru.c
@@ -12,10 +12,15 @@
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see .
*/
+#include
#include
-#include
+#include
+
+#include
+#include
#include "../msg_hash.h"
+#include "../verbosity.h"
#if defined(_MSC_VER) && !defined(_XBOX) && (_MSC_VER >= 1500 && _MSC_VER < 1900)
#if (_MSC_VER >= 1700)
@@ -40,12 +45,51 @@ int msg_hash_get_help_ru_enum(enum msg_hash_enums msg, char *s, size_t len)
return ret;
}
-const char *msg_hash_to_str_ru(enum msg_hash_enums msg)
+#ifdef HAVE_MENU
+static const char *menu_hash_to_str_ru_label_enum(enum msg_hash_enums msg)
{
+ if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END &&
+ msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN)
+ {
+ static char hotkey_lbl[128] = {0};
+ unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN;
+ snprintf(hotkey_lbl, sizeof(hotkey_lbl), "input_hotkey_binds_%d", idx);
+ return hotkey_lbl;
+ }
+
switch (msg)
{
-#include "msg_hash_ru.h"
+#include "msg_hash_lbl.h"
default:
+#if 0
+ RARCH_LOG("Unimplemented: [%d]\n", msg);
+#endif
+ break;
+ }
+
+ return "null";
+}
+#endif
+
+const char *msg_hash_to_str_ru(enum msg_hash_enums msg)
+{
+#ifdef HAVE_MENU
+ const char *ret = menu_hash_to_str_ru_label_enum(msg);
+
+ if (ret && !string_is_equal(ret, "null"))
+ return ret;
+#endif
+
+ switch (msg)
+ {
+#include "msg_hash_ru.h"
+ default:
+#if 0
+ RARCH_LOG("Unimplemented: [%d]\n", msg);
+ {
+ RARCH_LOG("[%d] : %s\n", msg - 1, msg_hash_to_str(((enum msg_hash_enums)(msg - 1))));
+ }
+#endif
break;
}
diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c
index a4d688a4b3..4e292bc7de 100644
--- a/menu/drivers/rgui.c
+++ b/menu/drivers/rgui.c
@@ -602,6 +602,7 @@ typedef struct
bitmapfont_lut_t *chn_10x10;
bitmapfont_lut_t *jpn_10x10;
bitmapfont_lut_t *kor_10x10;
+ bitmapfont_lut_t *rus_10x10;
} fonts;
frame_buf_t frame_buf;
@@ -1148,6 +1149,12 @@ static void rgui_fonts_free(rgui_t *rgui)
bitmapfont_free_lut(rgui->fonts.kor_10x10);
rgui->fonts.kor_10x10 = NULL;
}
+
+ if (rgui->fonts.rus_10x10)
+ {
+ bitmapfont_free_lut(rgui->fonts.rus_10x10);
+ rgui->fonts.rus_10x10 = NULL;
+ }
}
static bool rgui_fonts_init(rgui_t *rgui)
@@ -1212,6 +1219,26 @@ static bool rgui_fonts_init(rgui_t *rgui)
rgui->language = language;
break;
case RETRO_LANGUAGE_RUSSIAN:
+ rgui->fonts.eng_10x10 = bitmapfont_10x10_load(RETRO_LANGUAGE_ENGLISH);
+ rgui->fonts.rus_10x10 = bitmapfont_10x10_load(RETRO_LANGUAGE_RUSSIAN);
+
+ if (!rgui->fonts.eng_10x10 ||
+ !rgui->fonts.rus_10x10)
+ {
+ rgui_fonts_free(rgui);
+ *msg_hash_get_uint(MSG_HASH_USER_LANGUAGE) = RETRO_LANGUAGE_ENGLISH;
+ runloop_msg_queue_push(
+ msg_hash_to_str(MSG_RGUI_MISSING_FONTS), 1, 256, false, NULL,
+ MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
+ goto english;
+ }
+
+ rgui->font_width = FONT_10X10_WIDTH;
+ rgui->font_height = FONT_10X10_HEIGHT;
+ rgui->font_width_stride = FONT_10X10_WIDTH_STRIDE;
+ rgui->font_height_stride = FONT_10X10_HEIGHT_STRIDE;
+ rgui->language = language;
+ break;
case RETRO_LANGUAGE_ARABIC:
case RETRO_LANGUAGE_GREEK:
case RETRO_LANGUAGE_PERSIAN:
@@ -2975,7 +3002,7 @@ static void blit_line_cjk_shadow(
unsigned fb_width, int x, int y,
const char *message, uint16_t color, uint16_t shadow_color)
{
- uint16_t *frame_buf_data = rgui->frame_buf.data;
+ uint16_t *frame_buf_data = rgui->frame_buf.data;
bitmapfont_lut_t *font_eng = rgui->fonts.eng_10x10;
bitmapfont_lut_t *font_chn = rgui->fonts.chn_10x10;
bitmapfont_lut_t *font_jpn = rgui->fonts.jpn_10x10;
@@ -3041,6 +3068,121 @@ static void blit_line_cjk_shadow(
x += FONT_10X10_WIDTH_STRIDE;
}
}
+
+static void blit_line_rus(
+ rgui_t *rgui,
+ unsigned fb_width, int x, int y,
+ const char *message, uint16_t color, uint16_t shadow_color)
+{
+ uint16_t *frame_buf_data = rgui->frame_buf.data;
+ bitmapfont_lut_t *font_eng = rgui->fonts.eng_10x10;
+ bitmapfont_lut_t *font_rus = rgui->fonts.rus_10x10;
+
+ while (!string_is_empty(message))
+ {
+ /* Deal with spaces first, for efficiency */
+ if (*message == ' ')
+ message++;
+ else
+ {
+ unsigned i, j;
+ bool *symbol_lut;
+ uint32_t symbol = utf8_walk(&message);
+
+ if (symbol == 339) /* Latin small ligature oe */
+ symbol = 156;
+ if (symbol == 338) /* Latin capital ligature oe */
+ symbol = 140;
+
+ /* Find glyph LUT data */
+ if (symbol <= font_eng->glyph_max)
+ symbol_lut = font_eng->lut[symbol];
+ else if ((symbol >= font_rus->glyph_min) && (symbol <= font_rus->glyph_max))
+ symbol_lut = font_rus->lut[symbol - font_rus->glyph_min];
+ else
+ continue;
+
+ for (j = 0; j < FONT_10X10_HEIGHT; j++)
+ {
+ unsigned buff_offset = ((y + j) * fb_width) + x;
+
+ for (i = 0; i < FONT_10X10_WIDTH; i++)
+ {
+ if (*(symbol_lut + i + (j * FONT_10X10_WIDTH)))
+ *(frame_buf_data + buff_offset + i) = color;
+ }
+ }
+ }
+
+ x += FONT_10X10_WIDTH_STRIDE;
+ }
+}
+
+static void blit_line_rus_shadow(
+ rgui_t *rgui,
+ unsigned fb_width, int x, int y,
+ const char *message, uint16_t color, uint16_t shadow_color)
+{
+ uint16_t *frame_buf_data = rgui->frame_buf.data;
+ bitmapfont_lut_t *font_eng = rgui->fonts.eng_10x10;
+ bitmapfont_lut_t *font_rus = rgui->fonts.rus_10x10;
+ uint16_t color_buf[2];
+ uint16_t shadow_color_buf[2];
+
+ color_buf[0] = color;
+ color_buf[1] = shadow_color;
+
+ shadow_color_buf[0] = shadow_color;
+ shadow_color_buf[1] = shadow_color;
+
+ while (!string_is_empty(message))
+ {
+ /* Deal with spaces first, for efficiency */
+ if (*message == ' ')
+ message++;
+ else
+ {
+ unsigned i, j;
+ bool *symbol_lut;
+ uint32_t symbol = utf8_walk(&message);
+
+ if (symbol == 339) /* Latin small ligature oe */
+ symbol = 156;
+ if (symbol == 338) /* Latin capital ligature oe */
+ symbol = 140;
+
+ /* Find glyph LUT data */
+ if (symbol <= font_eng->glyph_max)
+ symbol_lut = font_eng->lut[symbol];
+ else if ((symbol >= font_rus->glyph_min) && (symbol <= font_rus->glyph_max))
+ symbol_lut = font_rus->lut[symbol - font_rus->glyph_min];
+ else
+ continue;
+
+ for (j = 0; j < FONT_10X10_HEIGHT; j++)
+ {
+ unsigned buff_offset = ((y + j) * fb_width) + x;
+
+ for (i = 0; i < FONT_10X10_WIDTH; i++)
+ {
+ if (*(symbol_lut + i + (j * FONT_10X10_WIDTH)))
+ {
+ uint16_t *frame_buf_ptr = frame_buf_data + buff_offset + i;
+
+ /* Text pixel + right shadow */
+ memcpy(frame_buf_ptr, color_buf, sizeof(color_buf));
+
+ /* Bottom shadow */
+ frame_buf_ptr += fb_width;
+ memcpy(frame_buf_ptr, shadow_color_buf, sizeof(shadow_color_buf));
+ }
+ }
+ }
+ }
+
+ x += FONT_10X10_WIDTH_STRIDE;
+ }
+}
#endif
static void (*blit_line)(rgui_t *rgui, unsigned fb_width, int x, int y,
@@ -3175,6 +3317,9 @@ static void rgui_set_blit_functions(unsigned language,
case RETRO_LANGUAGE_CHINESE_TRADITIONAL:
blit_line = blit_line_cjk_shadow;
break;
+ case RETRO_LANGUAGE_RUSSIAN:
+ blit_line = blit_line_rus_shadow;
+ break;
default:
if (extended_ascii)
blit_line = blit_line_extended_shadow;
@@ -3202,6 +3347,9 @@ static void rgui_set_blit_functions(unsigned language,
case RETRO_LANGUAGE_CHINESE_TRADITIONAL:
blit_line = blit_line_cjk;
break;
+ case RETRO_LANGUAGE_RUSSIAN:
+ blit_line = blit_line_rus;
+ break;
default:
if (extended_ascii)
blit_line = blit_line_extended;