From e51d1a3d2ac250cea25d2b7d73d6dcabb5946fc6 Mon Sep 17 00:00:00 2001 From: libretroadmin Date: Thu, 1 Jun 2023 00:08:00 +0200 Subject: [PATCH] Get rid of some old libtransistor files/codepaths --- Makefile.common | 9 +- gfx/drivers/switch_gfx.c | 427 ----------------------- gfx/drivers/switch_nx_gfx.c | 329 ++++++++++++++++- gfx/drivers_display/gfx_display_switch.c | 50 --- gfx/drivers_font/switch_font.c | 311 ----------------- griffin/griffin.c | 4 - 6 files changed, 329 insertions(+), 801 deletions(-) delete mode 100644 gfx/drivers/switch_gfx.c delete mode 100644 gfx/drivers_display/gfx_display_switch.c delete mode 100644 gfx/drivers_font/switch_font.c diff --git a/Makefile.common b/Makefile.common index 345183f65b..b9a0648eff 100644 --- a/Makefile.common +++ b/Makefile.common @@ -801,10 +801,6 @@ ifeq ($(HAVE_CORETEXT), 1) OBJ += gfx/drivers_font_renderer/coretext.o endif -ifeq ($(HAVE_LIBNX), 1) - OBJ += gfx/drivers_font/switch_font.o -endif - ifeq ($(HAVE_AUDIOIO), 1) OBJ += audio/drivers/audioio.o endif @@ -1175,15 +1171,12 @@ endif ifeq ($(TARGET), retroarch_switch) ifeq ($(HAVE_LIBNX), 1) - OBJ += gfx/drivers_display/gfx_display_switch.o \ - gfx/drivers/switch_nx_gfx.o \ + OBJ += gfx/drivers/switch_nx_gfx.o \ audio/drivers/switch_libnx_audren_audio.o \ audio/drivers/switch_libnx_audren_thread_audio.o ifeq ($(HAVE_OPENGL), 1) OBJ += gfx/drivers_context/switch_ctx.o endif - else - OBJ += gfx/drivers/switch_gfx.o endif OBJ += audio/drivers/switch_audio.o \ audio/drivers/switch_thread_audio.o \ diff --git a/gfx/drivers/switch_gfx.c b/gfx/drivers/switch_gfx.c deleted file mode 100644 index 68b526bf18..0000000000 --- a/gfx/drivers/switch_gfx.c +++ /dev/null @@ -1,427 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2018 - misson20000 - * Copyright (C) 2018 - m4xw - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * 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 -#include - -#include - -#ifdef HAVE_CONFIG_H -#include "../../config.h" -#endif - -#ifdef HAVE_MENU -#include "../../menu/menu_driver.h" -#endif - -#include "../font_driver.h" - -#include "../../configuration.h" -#include "../../command.h" -#include "../../driver.h" - -#include "../../retroarch.h" -#include "../../verbosity.h" - -#ifndef HAVE_THREADS -#include "../../tasks/tasks_internal.h" -#endif - -typedef struct -{ - bool vsync; - bool rgb32; - unsigned width, height; - unsigned rotation; - uint32_t last_width; - uint32_t last_height; - - struct video_viewport vp; - - struct - { - bool enable; - bool fullscreen; - - uint32_t *pixels; - - unsigned width; - unsigned height; - - unsigned tgtw; - unsigned tgth; - - struct scaler_ctx scaler; - } menu_texture; - surface_t surface; - revent_h vsync_h; - uint32_t image[1280*720]; - struct scaler_ctx scaler; -} switch_video_t; - -static void *switch_init(const video_info_t *video, - input_driver_t **input, void **input_data) -{ - unsigned x, y; - switch_video_t *sw = (switch_video_t*)calloc(1, sizeof(*sw)); - if (!sw) - return NULL; - - RARCH_LOG("loading switch gfx driver, width: %d, height: %d\n", video->width, video->height); - - result_t r = display_init(); - if (r != RESULT_OK) - goto error; - r = display_open_layer(&sw->surface); - - if (r != RESULT_OK) - { - display_finalize(); - goto error; - } - r = display_get_vsync_event(&sw->vsync_h); - - if (r != RESULT_OK) - { - display_close_layer(&sw->surface); - display_finalize(); - goto error; - } - - sw->vp.x = 0; - sw->vp.y = 0; - sw->vp.width = 1280; - sw->vp.height = 720; - sw->vp.full_width = 1280; - sw->vp.full_height = 720; - video_driver_set_size(sw->vp.width, sw->vp.height); - - sw->vsync = video->vsync; - sw->rgb32 = video->rgb32; - - *input = NULL; - *input_data = NULL; - - return sw; - -error: - free(sw); - return NULL; -} - -static void switch_wait_vsync(switch_video_t *sw) -{ - uint32_t handle_idx; - svcWaitSynchronization(&handle_idx, &sw->vsync_h, 1, 33333333); - svcResetSignal(sw->vsync_h); -} - -static bool switch_frame(void *data, const void *frame, - unsigned width, unsigned height, - uint64_t frame_count, unsigned pitch, - const char *msg, video_frame_info_t *video_info) -{ - static uint64_t last_frame = 0; - - unsigned x, y; - result_t r; - int tgtw, tgth, centerx, centery; - uint32_t *out_buffer = NULL; - switch_video_t *sw = data; - int xsf = 1280 / width; - int ysf = 720 / height; - int sf = xsf; -#ifdef HAVE_MENU - bool menu_is_alive = video_info->menu_is_alive; -#endif - bool statistics_show = video_info->statistics_show; - struct font_params - *osd_params = (struct font_params*) - &video_info->osd_stat_params; - - - if (ysf < sf) - sf = ysf; - - tgtw = width * sf; - tgth = height * sf; - centerx = (1280-tgtw)/2; - centery = (720-tgth)/2; - - /* clear image to black */ - for (y = 0; y < 720; y++) - for (x = 0; x < 1280; x++) - sw->image[y*1280+x] = 0xFF000000; - - if (width > 0 && height > 0) - { - if ( (sw->last_width != width) - || (sw->last_height != height)) - { - scaler_ctx_gen_reset(&sw->scaler); - - sw->scaler.in_width = width; - sw->scaler.in_height = height; - sw->scaler.in_stride = pitch; - sw->scaler.in_fmt = sw->rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565; - - sw->scaler.out_width = tgtw; - sw->scaler.out_height = tgth; - sw->scaler.out_stride = 1280 * sizeof(uint32_t); - sw->scaler.out_fmt = SCALER_FMT_ABGR8888; - - sw->scaler.scaler_type = SCALER_TYPE_POINT; - - if (!scaler_ctx_gen_filter(&sw->scaler)) - { - RARCH_ERR("failed to generate scaler for main image\n"); - return false; - } - - sw->last_width = width; - sw->last_height = height; - } - - scaler_ctx_scale(&sw->scaler, sw->image + (centery * 1280) + centerx, frame); - } - -#if defined(HAVE_MENU) - if (sw->menu_texture.enable) - { - menu_driver_frame(menu_is_alive, video_info); - - if (sw->menu_texture.pixels) - { -#if 0 - if (sw->menu_texture.fullscreen) - { -#endif - scaler_ctx_scale(&sw->menu_texture.scaler, sw->image + - ((720-sw->menu_texture.tgth)/2)*1280 + - ((1280-sw->menu_texture.tgtw)/2), sw->menu_texture.pixels); -#if 0 - } - else - { - } -#endif - } - } - else if (statistics_show) - { - if (osd_params) - font_driver_render_msg(sw, video_info->stat_text, - osd_params, NULL); - } -#endif - - r = surface_dequeue_buffer(&sw->surface, &out_buffer); - if (r != RESULT_OK) - return true; /* just skip the frame */ - - r = surface_wait_buffer(&sw->surface); - if (r != RESULT_OK) - return true; - gfx_slow_swizzling_blit(out_buffer, sw->image, 1280, 720, 0, 0); - - r = surface_queue_buffer(&sw->surface); - - if (r != RESULT_OK) - return false; - - last_frame = svcGetSystemTick(); - return true; -} - -static void switch_set_nonblock_state(void *data, bool toggle, bool c, unsigned d) -{ - switch_video_t *sw = data; - sw->vsync = !toggle; -} - -static bool switch_alive(void *data) { return true; } -static bool switch_focus(void *data) { return true; } -static bool switch_suppress_screensaver(void *data, bool enable) { return false; } -static bool switch_has_windowed(void *data) { return false; } - -static void switch_free(void *data) -{ - switch_video_t *sw = data; - svcCloseHandle(sw->vsync_h); - display_close_layer(&sw->surface); - display_finalize(); - free(sw); -} - -static bool switch_set_shader(void *data, - enum rarch_shader_type type, const char *path) -{ - (void) data; - (void) type; - (void) path; - - return false; -} - -static void switch_set_rotation(void *data, unsigned rotation) -{ - switch_video_t *sw = data; - if (!sw) - return; - sw->rotation = rotation; -} - -static void switch_viewport_info(void *data, struct video_viewport *vp) -{ - switch_video_t *sw = data; - *vp = sw->vp; -} - -static void switch_set_texture_frame( - void *data, const void *frame, bool rgb32, - unsigned width, unsigned height, float alpha) -{ - switch_video_t *sw = data; - - if ( !sw->menu_texture.pixels || - sw->menu_texture.width != width || - sw->menu_texture.height != height) - { - struct scaler_ctx *sctx; - int xsf, ysf, sf; - if (sw->menu_texture.pixels) - free(sw->menu_texture.pixels); - - sw->menu_texture.pixels = malloc(width * height * (rgb32 ? 4 : 2)); - if (!sw->menu_texture.pixels) - { - RARCH_ERR("failed to allocate buffer for menu texture\n"); - return; - } - - xsf = 1280 / width; - ysf = 720 / height; - sf = xsf; - - if (ysf < sf) - sf = ysf; - - sw->menu_texture.width = width; - sw->menu_texture.height = height; - sw->menu_texture.tgtw = width * sf; - sw->menu_texture.tgth = height * sf; - - sctx = &sw->menu_texture.scaler; - scaler_ctx_gen_reset(sctx); - - sctx->in_width = width; - sctx->in_height = height; - sctx->in_stride = width * (rgb32 ? 4 : 2); - sctx->in_fmt = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGB565; - - sctx->out_width = sw->menu_texture.tgtw; - sctx->out_height = sw->menu_texture.tgth; - sctx->out_stride = 1280 * 4; - sctx->out_fmt = SCALER_FMT_ABGR8888; - - sctx->scaler_type = SCALER_TYPE_POINT; - - if (!scaler_ctx_gen_filter(sctx)) - { - RARCH_ERR("failed to generate scaler for menu texture\n"); - return; - } - } - - memcpy(sw->menu_texture.pixels, frame, width * height * (rgb32 ? 4 : 2)); -} - -static void switch_set_texture_enable(void *data, bool enable, bool full_screen) -{ - switch_video_t *sw = data; - if (!sw) - return; - - sw->menu_texture.enable = enable; - sw->menu_texture.fullscreen = full_screen; -} - -static const video_poke_interface_t switch_poke_interface = { - NULL, /* get_flags */ - NULL, /* load_texture */ - NULL, /* unload_texture */ - NULL, /* set_video_mode */ - NULL, /* get_refresh_rate */ - NULL, /* set_filtering */ - NULL, /* get_video_output_size */ - NULL, /* get_video_output_prev */ - NULL, /* get_video_output_next */ - NULL, /* get_current_framebuffer */ - NULL, /* get_proc_address */ - NULL, /* set_aspect_ratio */ - NULL, /* apply_state_changes */ - switch_set_texture_frame, - switch_set_texture_enable, - NULL, /* set_osd_msg */ - NULL, /* show_mouse */ - NULL, /* grab_mouse_toggle */ - NULL, /* get_current_shader */ - NULL, /* get_current_software_framebuffer */ - NULL, /* get_hw_render_interface */ - NULL, /* set_hdr_max_nits */ - NULL, /* set_hdr_paper_white_nits */ - NULL, /* set_hdr_contrast */ - NULL /* set_hdr_expand_gamut */ -}; - -static void switch_get_poke_interface(void *data, - const video_poke_interface_t **iface) -{ - (void) data; - *iface = &switch_poke_interface; -} - -video_driver_t video_switch = { - switch_init, - switch_frame, - switch_set_nonblock_state, - switch_alive, - switch_focus, - switch_suppress_screensaver, - switch_has_windowed, - switch_set_shader, - switch_free, - "switch", - NULL, /* set_viewport */ - switch_set_rotation, - switch_viewport_info, - NULL, /* read_viewport */ - NULL, /* read_frame_raw */ -#ifdef HAVE_OVERLAY - NULL, /* overlay_interface */ -#endif - switch_get_poke_interface, -}; - -/* vim: set ts=3 sw=3 */ diff --git a/gfx/drivers/switch_nx_gfx.c b/gfx/drivers/switch_nx_gfx.c index a9676be272..ce42f9900f 100644 --- a/gfx/drivers/switch_nx_gfx.c +++ b/gfx/drivers/switch_nx_gfx.c @@ -15,14 +15,17 @@ */ #include +#include #include #include +#include +#include #include #include #include +#include -#include #include #include #include @@ -52,6 +55,330 @@ #include "../../tasks/tasks_internal.h" #endif +/* + * DISPLAY DRIVER + */ + +static void gfx_display_switch_draw(gfx_display_ctx_draw_t *draw, + void *data, unsigned video_width, unsigned video_height) { } + +static const float *gfx_display_switch_get_default_vertices(void) +{ + static float dummy[16] = {0.0f}; + return &dummy[0]; +} + +static const float *gfx_display_switch_get_default_tex_coords(void) +{ + static float dummy[16] = {0.0f}; + return &dummy[0]; +} + +gfx_display_ctx_driver_t gfx_display_ctx_switch = { + gfx_display_switch_draw, + NULL, /* draw_pipeline */ + NULL, /* blend_begin */ + NULL, /* blend_end */ + NULL, /* get_default_mvp */ + gfx_display_switch_get_default_vertices, + gfx_display_switch_get_default_tex_coords, + FONT_DRIVER_RENDER_SWITCH, + GFX_VIDEO_DRIVER_SWITCH, + "switch", + false, + NULL, /* scissor_begin */ + NULL /* scissor_end */ +}; + +/* + * FONT DRIVER + */ + +#define AVG_GLPYH_LIMIT 140 + +typedef struct +{ + struct font_atlas *atlas; + + const font_renderer_driver_t *font_driver; + void *font_data; +} switch_font_t; + +static void *switch_font_init(void *data, const char *font_path, + float font_size, bool is_threaded) +{ + switch_font_t *font = (switch_font_t *)calloc(1, sizeof(switch_font_t)); + + if (!font) + return NULL; + + if (!font_renderer_create_default(&font->font_driver, + &font->font_data, font_path, font_size)) + { + free(font); + return NULL; + } + + font->atlas = font->font_driver->get_atlas(font->font_data); + + return font; +} + +static void switch_font_free(void *data, bool is_threaded) +{ + switch_font_t *font = (switch_font_t *)data; + + if (!font) + return; + + if (font->font_driver && font->font_data) + font->font_driver->free(font->font_data); + + free(font); +} + +static int switch_font_get_message_width(void *data, const char *msg, + size_t msg_len, float scale) +{ + int i; + const struct font_glyph* glyph_q = NULL; + int delta_x = 0; + switch_font_t *font = (switch_font_t *)data; + + if (!font) + return 0; + + glyph_q = font->font_driver->get_glyph(font->font_data, '?'); + + for (i = 0; i < msg_len; i++) + { + const struct font_glyph *glyph; + const char *msg_tmp = &msg[i]; + unsigned code = utf8_walk(&msg_tmp); + unsigned skip = msg_tmp - &msg[i]; + + if (skip > 1) + i += skip - 1; + + /* Do something smarter here ... */ + if (!(glyph = + font->font_driver->get_glyph(font->font_data, code))) + if (!(glyph = glyph_q)) + continue; + + delta_x += glyph->advance_x; + } + + return delta_x * scale; +} + +static void switch_font_render_line( + switch_video_t *sw, + switch_font_t *font, const char *msg, size_t msg_len, + float scale, const unsigned int color, float pos_x, + float pos_y, unsigned text_align) +{ + int i; + const struct font_glyph* glyph_q = NULL; + int delta_x = 0; + int delta_y = 0; + unsigned fb_width = sw->vp.full_width; + unsigned fb_height = sw->vp.full_height; + int x = roundf(pos_x * fb_width); + int y = roundf((1.0f - pos_y) * fb_height); + + switch (text_align) + { + case TEXT_ALIGN_RIGHT: + x -= switch_font_get_message_width(font, msg, msg_len, scale); + break; + case TEXT_ALIGN_CENTER: + x -= switch_font_get_message_width(font, msg, msg_len, scale) / 2; + break; + } + + glyph_q = font->font_driver->get_glyph(font->font_data, '?'); + + for (i = 0; i < msg_len; i++) + { + const struct font_glyph *glyph; + int off_x, off_y, tex_x, tex_y, width, height; + const char *msg_tmp = &msg[i]; + unsigned code = utf8_walk(&msg_tmp); + unsigned skip = msg_tmp - &msg[i]; + + if (skip > 1) + i += skip - 1; + + /* Do something smarter here ... */ + if (!(glyph = + font->font_driver->get_glyph(font->font_data, code))) + if (!(glyph = glyph_q)) + continue; + + off_x = x + glyph->draw_offset_x + delta_x; + off_y = y + glyph->draw_offset_y + delta_y; + width = glyph->width; + height = glyph->height; + + tex_x = glyph->atlas_offset_x; + tex_y = glyph->atlas_offset_y; + + for (y = tex_y; y < tex_y + height; y++) + { + int x; + uint8_t *row = &font->atlas->buffer[y * font->atlas->width]; + for (x = tex_x; x < tex_x + width; x++) + { + int x1, y1; + if (!row[x]) + continue; + x1 = off_x + (x - tex_x); + y1 = off_y + (y - tex_y); + if (x1 < fb_width && y1 < fb_height) + sw->out_buffer[y1 * sw->stride / sizeof(uint32_t) + x1] = color; + } + } + + delta_x += glyph->advance_x; + delta_y += glyph->advance_y; + } +} + +static void switch_font_render_message( + switch_video_t *sw, + switch_font_t *font, const char *msg, float scale, + const unsigned int color, float pos_x, float pos_y, + unsigned text_align) +{ + struct font_line_metrics *line_metrics = NULL; + int lines = 0; + float line_height; + + if (!msg || !*msg || !sw) + return; + if (!sw || !sw->out_buffer) + return; + + /* If font line metrics are not supported just draw as usual */ + if (!font->font_driver->get_line_metrics || + !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) + { + size_t msg_len = strlen(msg); + if (msg_len <= AVG_GLPYH_LIMIT) + switch_font_render_line(sw, font, msg, msg_len, + scale, color, pos_x, pos_y, text_align); + return; + } + + line_height = scale / line_metrics->height; + + for (;;) + { + const char *delim = strchr(msg, '\n'); + size_t msg_len = delim ? + (delim - msg) : strlen(msg); + + /* Draw the line */ + if (msg_len <= AVG_GLPYH_LIMIT) + switch_font_render_line(sw, font, msg, msg_len, + scale, color, pos_x, pos_y - (float)lines * line_height, + text_align); + + if (!delim) + break; + + msg += msg_len + 1; + lines++; + } +} + +static void switch_font_render_msg( + void *userdata, + void *data, + const char *msg, + const struct font_params *params) +{ + float x, y, scale; + enum text_alignment text_align; + unsigned color, r, g, b, alpha; + switch_font_t *font = (switch_font_t *)data; + switch_video_t *sw = (switch_video_t*)userdata; + settings_t *settings = config_get_ptr(); + float video_msg_color_r = settings->floats.video_msg_color_r; + float video_msg_color_g = settings->floats.video_msg_color_g; + float video_msg_color_b = settings->floats.video_msg_color_b; + + if (!font || !msg || (msg && !*msg)) + return; + + if (params) + { + x = params->x; + y = params->y; + scale = params->scale; + text_align = params->text_align; + + r = FONT_COLOR_GET_RED(params->color); + g = FONT_COLOR_GET_GREEN(params->color); + b = FONT_COLOR_GET_BLUE(params->color); + alpha = FONT_COLOR_GET_ALPHA(params->color); + + color = params->color; + } + else + { + x = 0.0f; + y = 0.0f; + scale = 1.0f; + text_align = TEXT_ALIGN_LEFT; + + r = (video_msg_color_r * 255); + g = (video_msg_color_g * 255); + b = (video_msg_color_b * 255); + alpha = 255; + color = COLOR_ABGR(r, g, b, alpha); + + } + + switch_font_render_message(sw, font, msg, scale, + color, x, y, text_align); +} + +static const struct font_glyph *switch_font_get_glyph( + void *data, uint32_t code) +{ + switch_font_t *font = (switch_font_t *)data; + if (font && font->font_driver && font->font_driver->ident) + return font->font_driver->get_glyph((void *)font->font_driver, code); + return NULL; +} + +static bool switch_font_get_line_metrics(void* data, struct font_line_metrics **metrics) +{ + switch_font_t *font = (switch_font_t *)data; + if (font && font->font_driver && font->font_data) + return font->font_driver->get_line_metrics(font->font_data, metrics); + return false; +} + +font_renderer_t switch_font = +{ + switch_font_init, + switch_font_free, + switch_font_render_msg, + "switch", + switch_font_get_glyph, + NULL, /* bind_block */ + NULL, /* flush_block */ + switch_font_get_message_width, + switch_font_get_line_metrics +}; + +/* + * VIDEO DRIVER + */ + /* (C) libtransistor */ static int pdep(uint32_t mask, uint32_t value) { diff --git a/gfx/drivers_display/gfx_display_switch.c b/gfx/drivers_display/gfx_display_switch.c deleted file mode 100644 index f48c33386b..0000000000 --- a/gfx/drivers_display/gfx_display_switch.c +++ /dev/null @@ -1,50 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2018 - m4xw - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with RetroArch. - * If not, see . - */ -#include - -#include - -#include "../gfx_display.h" - -static void gfx_display_switch_draw(gfx_display_ctx_draw_t *draw, - void *data, unsigned video_width, unsigned video_height) { } - -static const float *gfx_display_switch_get_default_vertices(void) -{ - static float dummy[16] = {0.0f}; - return &dummy[0]; -} - -static const float *gfx_display_switch_get_default_tex_coords(void) -{ - static float dummy[16] = {0.0f}; - return &dummy[0]; -} - -gfx_display_ctx_driver_t gfx_display_ctx_switch = { - gfx_display_switch_draw, - NULL, /* draw_pipeline */ - NULL, /* blend_begin */ - NULL, /* blend_end */ - NULL, /* get_default_mvp */ - gfx_display_switch_get_default_vertices, - gfx_display_switch_get_default_tex_coords, - FONT_DRIVER_RENDER_SWITCH, - GFX_VIDEO_DRIVER_SWITCH, - "switch", - false, - NULL, /* scissor_begin */ - NULL /* scissor_end */ -}; diff --git a/gfx/drivers_font/switch_font.c b/gfx/drivers_font/switch_font.c deleted file mode 100644 index ebf0e17856..0000000000 --- a/gfx/drivers_font/switch_font.c +++ /dev/null @@ -1,311 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2018 - lifajucejo - * Copyright (C) 2018 - m4xw - * Copyright (C) 2018 - natinusala - * - * RetroArch is free software: you can redistribute it and/or modify it under the terms - * of the GNU General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * 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 "../font_driver.h" - -#include "../../configuration.h" - -#include "../common/switch_common.h" - -#define AVG_GLPYH_LIMIT 140 - -typedef struct -{ - struct font_atlas *atlas; - - const font_renderer_driver_t *font_driver; - void *font_data; -} switch_font_t; - -static void *switch_font_init(void *data, const char *font_path, - float font_size, bool is_threaded) -{ - switch_font_t *font = (switch_font_t *)calloc(1, sizeof(switch_font_t)); - - if (!font) - return NULL; - - if (!font_renderer_create_default(&font->font_driver, - &font->font_data, font_path, font_size)) - { - free(font); - return NULL; - } - - font->atlas = font->font_driver->get_atlas(font->font_data); - - return font; -} - -static void switch_font_free(void *data, bool is_threaded) -{ - switch_font_t *font = (switch_font_t *)data; - - if (!font) - return; - - if (font->font_driver && font->font_data) - font->font_driver->free(font->font_data); - - free(font); -} - -static int switch_font_get_message_width(void *data, const char *msg, - size_t msg_len, float scale) -{ - int i; - const struct font_glyph* glyph_q = NULL; - int delta_x = 0; - switch_font_t *font = (switch_font_t *)data; - - if (!font) - return 0; - - glyph_q = font->font_driver->get_glyph(font->font_data, '?'); - - for (i = 0; i < msg_len; i++) - { - const struct font_glyph *glyph; - const char *msg_tmp = &msg[i]; - unsigned code = utf8_walk(&msg_tmp); - unsigned skip = msg_tmp - &msg[i]; - - if (skip > 1) - i += skip - 1; - - /* Do something smarter here ... */ - if (!(glyph = - font->font_driver->get_glyph(font->font_data, code))) - if (!(glyph = glyph_q)) - continue; - - delta_x += glyph->advance_x; - } - - return delta_x * scale; -} - -static void switch_font_render_line( - switch_video_t *sw, - switch_font_t *font, const char *msg, size_t msg_len, - float scale, const unsigned int color, float pos_x, - float pos_y, unsigned text_align) -{ - int i; - const struct font_glyph* glyph_q = NULL; - int delta_x = 0; - int delta_y = 0; - unsigned fb_width = sw->vp.full_width; - unsigned fb_height = sw->vp.full_height; - int x = roundf(pos_x * fb_width); - int y = roundf((1.0f - pos_y) * fb_height); - - switch (text_align) - { - case TEXT_ALIGN_RIGHT: - x -= switch_font_get_message_width(font, msg, msg_len, scale); - break; - case TEXT_ALIGN_CENTER: - x -= switch_font_get_message_width(font, msg, msg_len, scale) / 2; - break; - } - - glyph_q = font->font_driver->get_glyph(font->font_data, '?'); - - for (i = 0; i < msg_len; i++) - { - const struct font_glyph *glyph; - int off_x, off_y, tex_x, tex_y, width, height; - const char *msg_tmp = &msg[i]; - unsigned code = utf8_walk(&msg_tmp); - unsigned skip = msg_tmp - &msg[i]; - - if (skip > 1) - i += skip - 1; - - /* Do something smarter here ... */ - if (!(glyph = - font->font_driver->get_glyph(font->font_data, code))) - if (!(glyph = glyph_q)) - continue; - - off_x = x + glyph->draw_offset_x + delta_x; - off_y = y + glyph->draw_offset_y + delta_y; - width = glyph->width; - height = glyph->height; - - tex_x = glyph->atlas_offset_x; - tex_y = glyph->atlas_offset_y; - - for (y = tex_y; y < tex_y + height; y++) - { - int x; - uint8_t *row = &font->atlas->buffer[y * font->atlas->width]; - for (x = tex_x; x < tex_x + width; x++) - { - int x1, y1; - if (!row[x]) - continue; - x1 = off_x + (x - tex_x); - y1 = off_y + (y - tex_y); - if (x1 < fb_width && y1 < fb_height) - sw->out_buffer[y1 * sw->stride / sizeof(uint32_t) + x1] = color; - } - } - - delta_x += glyph->advance_x; - delta_y += glyph->advance_y; - } -} - -static void switch_font_render_message( - switch_video_t *sw, - switch_font_t *font, const char *msg, float scale, - const unsigned int color, float pos_x, float pos_y, - unsigned text_align) -{ - struct font_line_metrics *line_metrics = NULL; - int lines = 0; - float line_height; - - if (!msg || !*msg || !sw) - return; - if (!sw || !sw->out_buffer) - return; - - /* If font line metrics are not supported just draw as usual */ - if (!font->font_driver->get_line_metrics || - !font->font_driver->get_line_metrics(font->font_data, &line_metrics)) - { - size_t msg_len = strlen(msg); - if (msg_len <= AVG_GLPYH_LIMIT) - switch_font_render_line(sw, font, msg, msg_len, - scale, color, pos_x, pos_y, text_align); - return; - } - - line_height = scale / line_metrics->height; - - for (;;) - { - const char *delim = strchr(msg, '\n'); - size_t msg_len = delim ? - (delim - msg) : strlen(msg); - - /* Draw the line */ - if (msg_len <= AVG_GLPYH_LIMIT) - switch_font_render_line(sw, font, msg, msg_len, - scale, color, pos_x, pos_y - (float)lines * line_height, - text_align); - - if (!delim) - break; - - msg += msg_len + 1; - lines++; - } -} - -static void switch_font_render_msg( - void *userdata, - void *data, - const char *msg, - const struct font_params *params) -{ - float x, y, scale; - enum text_alignment text_align; - unsigned color, r, g, b, alpha; - switch_font_t *font = (switch_font_t *)data; - switch_video_t *sw = (switch_video_t*)userdata; - settings_t *settings = config_get_ptr(); - float video_msg_color_r = settings->floats.video_msg_color_r; - float video_msg_color_g = settings->floats.video_msg_color_g; - float video_msg_color_b = settings->floats.video_msg_color_b; - - if (!font || !msg || (msg && !*msg)) - return; - - if (params) - { - x = params->x; - y = params->y; - scale = params->scale; - text_align = params->text_align; - - r = FONT_COLOR_GET_RED(params->color); - g = FONT_COLOR_GET_GREEN(params->color); - b = FONT_COLOR_GET_BLUE(params->color); - alpha = FONT_COLOR_GET_ALPHA(params->color); - - color = params->color; - } - else - { - x = 0.0f; - y = 0.0f; - scale = 1.0f; - text_align = TEXT_ALIGN_LEFT; - - r = (video_msg_color_r * 255); - g = (video_msg_color_g * 255); - b = (video_msg_color_b * 255); - alpha = 255; - color = COLOR_ABGR(r, g, b, alpha); - - } - - switch_font_render_message(sw, font, msg, scale, - color, x, y, text_align); -} - -static const struct font_glyph *switch_font_get_glyph( - void *data, uint32_t code) -{ - switch_font_t *font = (switch_font_t *)data; - if (font && font->font_driver && font->font_driver->ident) - return font->font_driver->get_glyph((void *)font->font_driver, code); - return NULL; -} - -static bool switch_font_get_line_metrics(void* data, struct font_line_metrics **metrics) -{ - switch_font_t *font = (switch_font_t *)data; - if (font && font->font_driver && font->font_data) - return font->font_driver->get_line_metrics(font->font_data, metrics); - return false; -} - -font_renderer_t switch_font = -{ - switch_font_init, - switch_font_free, - switch_font_render_msg, - "switch", - switch_font_get_glyph, - NULL, /* bind_block */ - NULL, /* flush_block */ - switch_font_get_message_width, - switch_font_get_line_metrics -}; diff --git a/griffin/griffin.c b/griffin/griffin.c index af7608df7f..aad26e03ac 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -1325,10 +1325,6 @@ MENU #endif #endif -#if defined(HAVE_LIBNX) -#include "../gfx/drivers_display/gfx_display_switch.c" -#endif - #ifdef HAVE_RGUI #include "../menu/drivers/rgui.c" #endif