(3DS) add experimental font and menu_display drivers.

This commit is contained in:
aliaspider 2016-09-29 20:14:12 +01:00
parent 5db13323f6
commit afd5e85a31
12 changed files with 843 additions and 28 deletions

View File

@ -44,7 +44,7 @@ endif
DEFINES :=
ifeq ($(GRIFFIN_BUILD), 1)
OBJ += griffin/griffin.o
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_RGUI
DEFINES += -DHAVE_GRIFFIN=1 -DHAVE_MENU -DHAVE_RGUI -DHAVE_XMB -DHAVE_MATERIALUI
DEFINES += -DHAVE_ZLIB -DHAVE_RPNG -DHAVE_RJPEG -DHAVE_RBMP -DHAVE_RTGA -DWANT_ZLIB -DHAVE_BUILTIN_AUTOCONFIG
else
HAVE_MENU_COMMON = 1
@ -65,6 +65,8 @@ else
OBJ := $(filter-out $(BLACKLIST),$(OBJ))
OBJ += gfx/drivers/ctr_gfx.o
OBJ += gfx/drivers_font/ctr_font.o
OBJ += menu/drivers_display/menu_display_ctr.o
OBJ += input/drivers/ctr_input.o
OBJ += input/drivers_joypad/ctr_joypad.o
OBJ += audio/drivers/ctr_csnd_audio.o

View File

@ -21,5 +21,6 @@ void dump_result_value(Result val);
#define DEBUG_ERROR(X) do{if(X)dump_result_value(X)}while(0)
#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H"
#define PRINTFPOS_STR(X,Y) "\x1b["X";"Y"H"
#define PRINTF_LINE(X) "\x1b["X";0H"
#endif //_CTR_DEBUG_H__

View File

@ -1,6 +1,9 @@
#ifndef CTR_COMMON_H__
#define CTR_COMMON_H__
#define COLOR_ABGR(r, g, b, a) (((unsigned)(a) << 24) | ((b) << 16) | ((g) << 8) | ((r) << 0))
#define CTR_TOP_FRAMEBUFFER_WIDTH 400
#define CTR_TOP_FRAMEBUFFER_HEIGHT 240
@ -76,12 +79,40 @@ typedef struct ctr_video
bool keep_aspect;
bool should_resize;
bool lcd_buttom_on;
bool msg_rendering_enabled;
void* empty_framebuffer;
aptHookCookie lcd_aptHook;
ctr_video_mode_enum video_mode;
int current_buffer_top;
struct
{
ctr_vertex_t* buffer;
ctr_vertex_t* current;
int size;
}vertex_cache;
} ctr_video_t;
typedef struct ctr_texture
{
int width;
int height;
enum texture_filter_type type;
void* data;
} ctr_texture_t;
static INLINE void ctr_set_scale_vector(ctr_scale_vector_t* vec,
int viewport_width, int viewport_height,
int texture_width, int texture_height)
{
vec->x = -2.0 / viewport_width;
vec->y = -2.0 / viewport_height;
vec->u = 1.0 / texture_width;
vec->v = -1.0 / texture_height;
}
#endif // CTR_COMMON_H__

View File

@ -20,6 +20,7 @@
#include <3ds.h>
#include <retro_inline.h>
#include <formats/image.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@ -28,11 +29,14 @@
#include "../../ctr/gpu_old.h"
#include "ctr_gu.h"
#include "../../menu/menu_driver.h"
#include "../../configuration.h"
#include "../../command.h"
#include "../../driver.h"
#include "../../retroarch.h"
#include "../../verbosity.h"
#include "../../performance_counters.h"
#include "../common/ctr_common.h"
@ -80,16 +84,6 @@ static INLINE void ctr_check_3D_slider(ctr_video_t* ctr)
}
}
static INLINE void ctr_set_scale_vector(ctr_scale_vector_t* vec,
int viewport_width, int viewport_height,
int texture_width, int texture_height)
{
vec->x = -2.0 / viewport_width;
vec->y = -2.0 / viewport_height;
vec->u = 1.0 / texture_width;
vec->v = -1.0 / texture_height;
}
static INLINE void ctr_set_screen_coords(ctr_video_t * ctr)
{
if (ctr->rotation == 0)
@ -279,6 +273,7 @@ static void* ctr_init(const video_info_t* video,
float refresh_rate;
void* ctrinput = NULL;
ctr_video_t* ctr = (ctr_video_t*)linearAlloc(sizeof(ctr_video_t));
settings_t *settings = config_get_ptr();
if (!ctr)
return NULL;
@ -292,14 +287,19 @@ static void* ctr_init(const video_info_t* video,
ctr->vp.height = CTR_TOP_FRAMEBUFFER_HEIGHT;
ctr->vp.full_width = CTR_TOP_FRAMEBUFFER_WIDTH;
ctr->vp.full_height = CTR_TOP_FRAMEBUFFER_HEIGHT;
video_driver_set_size(&ctr->vp.width, &ctr->vp.height);
ctr->drawbuffers.top.left = vramAlloc(CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * 2 * sizeof(uint32_t));
ctr->drawbuffers.top.right = (void*)((uint32_t*)ctr->drawbuffers.top.left + CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT);
ctr->display_list_size = 0x400;
ctr->display_list_size = 0x10000;
ctr->display_list = linearAlloc(ctr->display_list_size * sizeof(uint32_t));
GPU_Reset(NULL, ctr->display_list, ctr->display_list_size);
ctr->vertex_cache.size = 0x1000;
ctr->vertex_cache.buffer = linearAlloc(ctr->vertex_cache.size * sizeof(ctr_vertex_t));
ctr->vertex_cache.current = ctr->vertex_cache.buffer;
ctr->rgb32 = video->rgb32;
ctr->texture_width = video->input_scale * RARCH_SCALE_BASE;
ctr->texture_height = video->input_scale * RARCH_SCALE_BASE;
@ -413,11 +413,23 @@ static void* ctr_init(const video_info_t* video,
driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate);
aptHook(&ctr->lcd_aptHook, ctr_lcd_aptHook, ctr);
if (!font_driver_init_first(NULL, NULL, ctr, *settings->path.font
? settings->path.font : NULL, settings->video.font_size, false,
FONT_DRIVER_RENDER_CTR))
{
RARCH_ERR("Font: Failed to initialize font renderer.\n");
return false;
}
ctr->msg_rendering_enabled = false;
// DEBUG_HOLD();
return ctr;
}
static bool ctr_frame(void* data, const void* frame,
unsigned width, unsigned height,
unsigned width, unsigned height,
uint64_t frame_count,
unsigned pitch, const char* msg)
{
@ -677,7 +689,6 @@ static bool ctr_frame(void* data, const void* frame,
if (ctr->menu_texture_enable)
{
GSPGPU_FlushDataCache(ctr->menu.texture_linear,
ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t));
@ -706,8 +717,20 @@ static bool ctr_frame(void* data, const void* frame,
CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
}
ctr->msg_rendering_enabled = true;
menu_driver_ctl(RARCH_MENU_CTL_FRAME, NULL);
ctr->msg_rendering_enabled = false;
}
if (font_driver_has_render_msg() && msg)
font_driver_render_msg(NULL, msg, NULL);
// font_driver_render_msg(NULL, "TEST: 123 ABC àüî", NULL);
GPU_FinishDrawing();
GPUCMD_Finalize();
ctrGuFlushAndRun(true);
@ -815,7 +838,9 @@ static void ctr_free(void* data)
linearFree(ctr->menu.texture_swizzled);
linearFree(ctr->menu.frame_coords);
linearFree(ctr->empty_framebuffer);
linearFree(ctr->vertex_cache.buffer);
linearFree(ctr);
// DEBUG_HOLD();
// gfxExit();
}
@ -929,9 +954,87 @@ static void ctr_viewport_info(void* data, struct video_viewport* vp)
*vp = ctr->vp;
}
static uintptr_t ctr_load_texture(void *video_data, void *data,
bool threaded, enum texture_filter_type filter_type)
{
struct texture_image *image = (struct texture_image*)data;
ctr_texture_t* texture = calloc(1, sizeof(ctr_texture_t));
uint32_t texsize = image->width * image->height * sizeof(uint32_t);
void* tmpdata;
// texture->data = vramAlloc(image->width * image->height * sizeof(uint32_t));
// if(!texture->data)
texture->data = linearAlloc(image->width * image->height * sizeof(uint32_t));
texture->type = filter_type;
texture->width = image->width;
texture->height = image->height;
if ((!texture->data))
{
free(texture);
return 0;
}
if ((texture->width == 1) && (texture->height == 1))
{
*(uint32_t*)texture->data = *image->pixels;
}
else
{
tmpdata = linearAlloc(image->width * image->height * sizeof(uint32_t));
// memcpy(tmpdata, image->pixels, image->width * image->height * sizeof(uint32_t));
int i;
uint32_t* src = (uint32_t*)image->pixels;
uint32_t* dst = (uint32_t*)tmpdata;
for (i = 0; i < image->width * image->height; i++)
{
*dst = ((*src >> 8) & 0x00FF00) | ((*src >> 24) & 0xFF)| ((*src << 8) & 0xFF0000)| ((*src << 24) & 0xFF000000);
dst++;
src++;
}
GSPGPU_FlushDataCache(tmpdata, image->width * image->height * sizeof(uint32_t));
// printf("ctrGuCopyImage 0x%08X, %i, %i, 0x%08X, %i\n", tmpdata, image->width, image->height, texture->data, texture->width);
ctrGuCopyImage(true, tmpdata, image->width, image->height, CTRGU_RGBA8, false,
texture->data, texture->width, CTRGU_RGBA8, true);
// gspWaitForEvent(GSPGPU_EVENT_PPF, false);
linearFree(tmpdata);
}
return (uintptr_t)texture;
}
static void ctr_unload_texture(void *data, uintptr_t handle)
{
struct ctr_texture *texture = (struct ctr_texture*)handle;
if (!texture)
return;
if (texture->data)
{
if(((u32)texture->data & 0xFF000000) == 0x1F000000)
vramFree(texture->data);
else
linearFree(texture->data);
}
free(texture);
}
static void ctr_set_osd_msg(void *data, const char *msg,
const struct font_params *params, void *font)
{
ctr_video_t* ctr = (ctr_video_t*)data;
if (ctr->msg_rendering_enabled)
font_driver_render_msg(font, msg, params);
}
static const video_poke_interface_t ctr_poke_interface = {
NULL,
NULL,
ctr_load_texture,
ctr_unload_texture,
NULL,
ctr_set_filtering,
NULL, /* get_video_output_size */
@ -944,6 +1047,7 @@ static const video_poke_interface_t ctr_poke_interface = {
#ifdef HAVE_MENU
ctr_set_texture_frame,
ctr_set_texture_enable,
ctr_set_osd_msg,
#endif
NULL,
NULL,

View File

@ -23,6 +23,8 @@
#include <string.h>
#include <retro_inline.h>
#include "ctr/ctr_debug.h"
#define VIRT_TO_PHYS(vaddr) \
(((u32)(vaddr)) >= 0x14000000 && ((u32)(vaddr)) < 0x1c000000)?(void*)((u32)(vaddr) + 0x0c000000):\
(((u32)(vaddr)) >= 0x1F000000 && ((u32)(vaddr)) < 0x1F600000)?(void*)((u32)(vaddr) - 0x07000000):\
@ -51,16 +53,6 @@
#define CTR_CPU_TICKS_PER_SECOND 268123480
#define CTR_CPU_TICKS_PER_FRAME 4481134
#ifndef DEBUG_HOLD
void wait_for_input(void);
#define PRINTFPOS(X,Y) "\x1b["#X";"#Y"H"
#define PRINTF_LINE(X) "\x1b["X";0H"
#define DEBUG_HOLD() do{printf("%s@%s:%d.\n",__FUNCTION__, __FILE__, __LINE__);fflush(stdout);wait_for_input();}while(0)
#define DEBUG_VAR(X) printf( "%-20s: 0x%08X\n", #X, (u32)(X))
#define DEBUG_VAR64(X) printf( #X"\r\t\t\t\t : 0x%016llX\n", (u64)(X))
#endif
extern u32* gpuCmdBuf;
extern u32 gpuCmdBufOffset;
extern u32 __linear_heap_size;

436
gfx/drivers_font/ctr_font.c Normal file
View File

@ -0,0 +1,436 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <encodings/utf.h>
#include <3ds.h>
#include "../font_driver.h"
#include "../video_driver.h"
#include "../common/ctr_common.h"
#include "../drivers/ctr_gu.h"
#include "../../ctr/gpu_old.h"
#include "../../configuration.h"
#include "../../verbosity.h"
typedef struct
{
ctr_texture_t texture;
ctr_scale_vector_t scale_vector;
const font_renderer_driver_t* font_driver;
void* font_data;
} ctr_font_t;
static void* ctr_font_init_font(void* gl_data, const char* font_path, float font_size)
{
const struct font_atlas* atlas = NULL;
ctr_font_t* font = (ctr_font_t*)calloc(1, sizeof(*font));
if (!font)
return NULL;
font_size = 10;
if (!font_renderer_create_default((const void**)&font->font_driver,
&font->font_data, font_path, font_size))
{
RARCH_WARN("Couldn't initialize font renderer.\n");
free(font);
return NULL;
}
atlas = font->font_driver->get_atlas(font->font_data);
font->texture.width = next_pow2(atlas->width);
font->texture.height = next_pow2(atlas->height);
font->texture.data = vramAlloc(font->texture.width * font->texture.height);
uint8_t* tmp = linearAlloc(font->texture.width * font->texture.height);
int i, j;
const uint8_t* src = atlas->buffer;
for (j = 0; (j < atlas->height) && (j < font->texture.height); j++)
for (i = 0; (i < atlas->width) && (i < font->texture.width); i++)
{
int pos = (i & 0x1) << 0 | ((i & 0x2) << 1) | ((i & 0x4) << 2) |
(j & 0x1) << 1 | ((j & 0x2) << 2) | ((j & 0x4) << 3);
tmp[((i >> 3) << 6) + ((j >> 3) * ((font->texture.width >> 3) << 6)) + pos ] = src[i + j * atlas->width];
}
GSPGPU_FlushDataCache(tmp, font->texture.width * font->texture.height);
ctrGuCopyImage(true, tmp, font->texture.width >> 2, font->texture.height, CTRGU_RGBA8, true,
font->texture.data, font->texture.width >> 2, CTRGU_RGBA8, true);
linearFree(tmp);
ctr_set_scale_vector(&font->scale_vector, 400, 240, font->texture.width, font->texture.height);
return font;
}
static void ctr_font_free_font(void* data)
{
ctr_font_t* font = (ctr_font_t*)data;
if (!font)
return;
if (font->font_driver && font->font_data)
font->font_driver->free(font->font_data);
vramFree(font->texture.data);
free(font);
}
static int ctr_font_get_message_width(void* data, const char* msg,
unsigned msg_len, float scale)
{
ctr_font_t* font = (ctr_font_t*)data;
unsigned i;
int delta_x = 0;
if (!font)
return 0;
for (i = 0; i < msg_len; i++)
{
const char* msg_tmp = &msg[i];
unsigned code = utf8_walk(&msg_tmp);
unsigned skip = msg_tmp - &msg[i];
if (skip > 1)
i += skip - 1;
const struct font_glyph* glyph =
font->font_driver->get_glyph(font->font_data, code);
if (!glyph) /* Do something smarter here ... */
glyph = font->font_driver->get_glyph(font->font_data, '?');
if (!glyph)
continue;
delta_x += glyph->advance_x;
}
return delta_x * scale;
}
static void ctr_font_render_line(
ctr_font_t* font, const char* msg, unsigned msg_len,
float scale, const unsigned int color, float pos_x,
float pos_y, unsigned text_align)
{
int x, y, delta_x, delta_y;
unsigned width, height;
unsigned i;
ctr_video_t* ctr = (ctr_video_t*)video_driver_get_ptr(false);
ctr_vertex_t* v;
video_driver_get_size(&width, &height);
x = roundf(pos_x * width);
y = roundf((1.0f - pos_y) * height);
delta_x = 0;
delta_y = 0;
switch (text_align)
{
case TEXT_ALIGN_RIGHT:
x -= ctr_font_get_message_width(font, msg, msg_len, scale);
break;
case TEXT_ALIGN_CENTER:
x -= ctr_font_get_message_width(font, msg, msg_len, scale) / 2;
break;
}
if ((ctr->vertex_cache.size - (ctr->vertex_cache.current - ctr->vertex_cache.buffer)) < msg_len)
ctr->vertex_cache.current = ctr->vertex_cache.buffer;
v = ctr->vertex_cache.current;
for (i = 0; i < msg_len; i++)
{
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;
const struct font_glyph* glyph =
font->font_driver->get_glyph(font->font_data, code);
if (!glyph) /* Do something smarter here ... */
glyph = font->font_driver->get_glyph(font->font_data, '?');
if (!glyph)
continue;
off_x = glyph->draw_offset_x;
off_y = glyph->draw_offset_y;
tex_x = glyph->atlas_offset_x;
tex_y = glyph->atlas_offset_y;
width = glyph->width;
height = glyph->height;
v->x0 = x + off_x + delta_x * scale;
v->y0 = y + off_y + delta_y * scale;
v->u0 = tex_x;
v->v0 = tex_y;
v->x1 = v->x0 + width * scale;
v->y1 = v->y0 + height * scale;
v->u1 = v->u0 + width;
v->v1 = v->v0 + height;
v++;
delta_x += glyph->advance_x;
delta_y += glyph->advance_y;
}
ctrGuSetVertexShaderFloatUniform(0, (float*)&font->scale_vector, 1);
GSPGPU_FlushDataCache(ctr->vertex_cache.current, (v - ctr->vertex_cache.current) * sizeof(ctr_vertex_t));
ctrGuSetAttributeBuffers(2,
VIRT_TO_PHYS(ctr->vertex_cache.current),
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 |
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4,
sizeof(ctr_vertex_t));
GPU_SetTexEnv(0,
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
0,
GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_R, GPU_TEVOP_RGB_SRC_ALPHA, 0),
GPU_MODULATE, GPU_MODULATE,
color);
// printf("%s\n", msg);
// DEBUG_VAR(color);
// GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_R, 0, 0), GPU_REPLACE, GPU_REPLACE, 0);
ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(font->texture.data), font->texture.width, font->texture.height,
GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST) |
GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
GPU_L8);
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, v - ctr->vertex_cache.current);
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
{
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.right),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, v - ctr->vertex_cache.current);
}
// v = font->vertices;
// v->x0 = 0;
// v->y0 = 0;
// v->u0 = 0;
// v->v0 = 0;
// v->x1 = font->texture.width;
// v->y1 = font->texture.height;
// v->u1 = font->texture.width;
// v->v1 = font->texture.height;
// GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0);
// DEBUG_VAR(v - font->vertices);
// v = font->vertices;
// printf("OSDMSG: %s\n", msg);
// printf("vertex : (%i,%i,%i,%i) - (%i,%i,%i,%i)\n",
// v->x0, v->y0, v->x1, v->y1,
// v->u0, v->v0, v->u1, v->v1);
// printf("%s\n", msg);
ctr->vertex_cache.current = v;
}
static void ctr_font_render_message(
ctr_font_t* font, const char* msg, float scale,
const unsigned int color, float pos_x, float pos_y,
unsigned text_align)
{
int lines = 0;
float line_height;
if (!msg || !*msg)
return;
/* If the font height is not supported just draw as usual */
if (!font->font_driver->get_line_height)
{
ctr_font_render_line(font, msg, strlen(msg),
scale, color, pos_x, pos_y, text_align);
return;
}
line_height = scale / font->font_driver->get_line_height(font->font_data);
for (;;)
{
const char* delim = strchr(msg, '\n');
/* Draw the line */
if (delim)
{
unsigned msg_len = delim - msg;
ctr_font_render_line(font, msg, msg_len,
scale, color, pos_x, pos_y - (float)lines * line_height,
text_align);
msg += msg_len + 1;
lines++;
}
else
{
unsigned msg_len = strlen(msg);
ctr_font_render_line(font, msg, msg_len,
scale, color, pos_x, pos_y - (float)lines * line_height,
text_align);
break;
}
}
}
static void ctr_font_render_msg(void* data, const char* msg,
const void* userdata)
{
float x, y, scale, drop_mod, drop_alpha;
unsigned color, color_dark, r, g, b, alpha, r_dark, g_dark, b_dark, alpha_dark;
unsigned width, height;
int drop_x, drop_y;
unsigned max_glyphs;
enum text_alignment text_align;
settings_t* settings = config_get_ptr();
ctr_font_t* font = (ctr_font_t*)data;
const struct font_params* params = (const struct font_params*)userdata;
if (!font || !msg || !*msg)
return;
video_driver_get_size(&width, &height);
if (params)
{
// printf("%s\n", msg);
x = params->x;
y = params->y;
scale = params->scale;
text_align = params->text_align;
drop_x = params->drop_x;
drop_y = params->drop_y;
drop_mod = params->drop_mod;
drop_alpha = params->drop_alpha;
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;
// color = COLOR_ABGR(r, g, b, alpha);
}
else
{
x = settings->video.msg_pos_x;
y = settings->video.msg_pos_y;
scale = 1.0f;
text_align = TEXT_ALIGN_LEFT;
r = (settings->video.msg_color_r * 255);
g = (settings->video.msg_color_g * 255);
b = (settings->video.msg_color_b * 255);
alpha = 255;
color = COLOR_ABGR(r, g, b, alpha);
drop_x = -2;
drop_y = -2;
drop_mod = 0.3f;
drop_alpha = 1.0f;
}
max_glyphs = strlen(msg);
if (drop_x || drop_y)
max_glyphs *= 2;
if (drop_x || drop_y)
{
r_dark = r * drop_mod;
g_dark = g * drop_mod;
b_dark = b * drop_mod;
alpha_dark = alpha * drop_alpha;
color_dark = COLOR_ABGR(r_dark, g_dark, b_dark, alpha_dark);
ctr_font_render_message(font, msg, scale, color_dark,
x + scale * drop_x / width, y +
scale * drop_y / height, text_align);
}
ctr_font_render_message(font, msg, scale,
color, x, y, text_align);
}
static const struct font_glyph* ctr_font_get_glyph(
void* data, uint32_t code)
{
ctr_font_t* font = (ctr_font_t*)data;
if (!font || !font->font_driver)
return NULL;
if (!font->font_driver->ident)
return NULL;
return font->font_driver->get_glyph((void*)font->font_driver, code);
}
static void ctr_font_flush_block(void* data)
{
(void)data;
}
static void ctr_font_bind_block(void* data, void* userdata)
{
(void)data;
}
font_renderer_t ctr_font =
{
ctr_font_init_font,
ctr_font_free_font,
ctr_font_render_msg,
"ctrfont",
ctr_font_get_glyph,
ctr_font_bind_block,
ctr_font_flush_block,
ctr_font_get_message_width,
};

View File

@ -201,6 +201,34 @@ static bool vita2d_font_init_first(
}
#endif
#ifdef _3DS
static const font_renderer_t *ctr_font_backends[] = {
&ctr_font
};
static bool ctr_font_init_first(
const void **font_driver, void **font_handle,
void *video_data, const char *font_path, float font_size)
{
unsigned i;
for (i = 0; ctr_font_backends[i]; i++)
{
void *data = ctr_font_backends[i]->init(
video_data, font_path, font_size);
if (!data)
continue;
*font_driver = ctr_font_backends[i];
*font_handle = data;
return true;
}
return false;
}
#endif
static bool font_init_first(
const void **font_driver, void **font_handle,
void *video_data, const char *font_path, float font_size,
@ -230,6 +258,11 @@ static bool font_init_first(
case FONT_DRIVER_RENDER_VITA2D:
return vita2d_font_init_first(font_driver, font_handle,
video_data, font_path, font_size);
#endif
#ifdef _3DS
case FONT_DRIVER_RENDER_CTR:
return ctr_font_init_first(font_driver, font_handle,
video_data, font_path, font_size);
#endif
case FONT_DRIVER_RENDER_DONT_CARE:
/* TODO/FIXME - lookup graphics driver's 'API' */

View File

@ -30,6 +30,7 @@ enum font_driver_render_api
FONT_DRIVER_RENDER_OPENGL_API,
FONT_DRIVER_RENDER_DIRECT3D_API,
FONT_DRIVER_RENDER_VITA2D,
FONT_DRIVER_RENDER_CTR,
FONT_DRIVER_RENDER_VULKAN_API
};
@ -151,6 +152,7 @@ extern font_renderer_t d3d_xbox360_font;
extern font_renderer_t d3d_xdk1_font;
extern font_renderer_t d3d_win32_font;
extern font_renderer_t vita2d_vita_font;
extern font_renderer_t ctr_font;
extern font_renderer_t vulkan_raster_font;
extern font_renderer_driver_t stb_font_renderer;

View File

@ -381,6 +381,11 @@ FONTS
#include "../gfx/drivers_font/vita2d_font.c"
#endif
#if defined(_3DS)
#include "../gfx/drivers_font/ctr_font.c"
#endif
#if defined(HAVE_VULKAN)
#include "../gfx/drivers_font/vulkan_raster_font.c"
#endif
@ -950,6 +955,10 @@ MENU
#include "../menu/drivers_display/menu_display_vita2d.c"
#endif
#ifdef _3DS
#include "../menu/drivers_display/menu_display_ctr.c"
#endif
#endif
@ -957,7 +966,7 @@ MENU
#include "../menu/drivers/rgui.c"
#endif
#if defined(HAVE_OPENGL) || defined(HAVE_VITA2D)
#if defined(HAVE_OPENGL) || defined(HAVE_VITA2D) || defined(_3DS)
#ifdef HAVE_XMB
#include "../menu/drivers/xmb.c"
#endif

View File

@ -0,0 +1,196 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Daniel De Matteis
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include <retro_miscellaneous.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
#endif
#include "../menu_display.h"
#include "../../config.def.h"
#include "../../retroarch.h"
#include "../../gfx/font_driver.h"
#include "../../gfx/video_context_driver.h"
#include "../../gfx/video_shader_driver.h"
#include "../../gfx/common/ctr_common.h"
#include "../../gfx/drivers/ctr_gu.h"
#include "../../ctr/gpu_old.h"
static const float *menu_display_ctr_get_default_vertices(void)
{
return NULL;
}
static const float *menu_display_ctr_get_default_tex_coords(void)
{
return NULL;
}
static void *menu_display_ctr_get_default_mvp(void)
{
return NULL;
}
static void menu_display_ctr_blend_begin(void)
{
}
static void menu_display_ctr_blend_end(void)
{
}
static void menu_display_ctr_viewport(void *data)
{
}
static void menu_display_ctr_draw(void *data)
{
struct ctr_texture *texture = NULL;
const float *color = NULL;
ctr_video_t *ctr = (ctr_video_t*)video_driver_get_ptr(false);
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
if (!ctr || !draw)
return;
texture = (struct ctr_texture*)draw->texture;
color = draw->coords->color;
if (!texture)
return;
ctr_scale_vector_t scale_vector;
ctr_set_scale_vector(&scale_vector,
CTR_TOP_FRAMEBUFFER_WIDTH, CTR_TOP_FRAMEBUFFER_HEIGHT,
texture->width, texture->height);
ctrGuSetVertexShaderFloatUniform(0, (float*)&scale_vector, 1);
if ((ctr->vertex_cache.size - (ctr->vertex_cache.current - ctr->vertex_cache.buffer)) < 1)
ctr->vertex_cache.current = ctr->vertex_cache.buffer;
ctr_vertex_t* v = ctr->vertex_cache.current++;
v->x0 = draw->x;
v->y0 = 240 - draw->height - draw->y;
v->x1 = draw->x + draw->width;
v->y1 = v->y0 + draw->height;
v->u0 = 0;
v->v0 = 0;
v->u1 = texture->width;
v->v1 = texture->height;
ctrGuSetAttributeBuffers(2,
VIRT_TO_PHYS(v),
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 |
CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4,
sizeof(ctr_vertex_t));
color = draw->coords->color;
int colorR = (int)((*color++)*255.f);
int colorG = (int)((*color++)*255.f);
int colorB = (int)((*color++)*255.f);
int colorA = (int)((*color++)*255.f);
GPU_SetTexEnv(0,
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
0,
0,
GPU_MODULATE, GPU_MODULATE,
COLOR_ABGR(colorR,colorG,colorB,colorA)
);
// GPU_SetTexEnv(0,
// GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, 0),
// GPU_TEVSOURCES(GPU_CONSTANT, GPU_CONSTANT, 0),
// 0,
// GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, 0),
// GPU_REPLACE, GPU_REPLACE,
// 0x3FFFFFFF);
ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(texture->data), texture->width, texture->height,
GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
GPU_RGBA8);
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.left),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
if (ctr->video_mode == CTR_VIDEO_MODE_3D)
{
GPU_SetViewport(NULL,
VIRT_TO_PHYS(ctr->drawbuffers.top.right),
0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT,
CTR_TOP_FRAMEBUFFER_WIDTH);
GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
}
GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0);
// printf("(%i,%i,%i,%i) , (%i,%i)\n", (int)draw->x, (int)draw->y, (int)draw->width, (int)draw->height, texture->width, texture->height);
}
static void menu_display_ctr_draw_pipeline(void *data)
{
}
static void menu_display_ctr_restore_clear_color(void)
{
// ctr_set_clear_color(RGBA8(0x00, 0x00, 0x00, 0xFF));
}
static void menu_display_ctr_clear_color(menu_display_ctx_clearcolor_t *clearcolor)
{
if (!clearcolor)
return;
// ctr_set_clear_color(RGBA8((int)(clearcolor->r*255.f),
// (int)(clearcolor->g*255.f),
// (int)(clearcolor->b*255.f),
// (int)(clearcolor->a*255.f)));
// ctr_clear_screen();
}
static bool menu_display_ctr_font_init_first(
void **font_handle, void *video_data,
const char *font_path, float font_size)
{
return font_driver_init_first(NULL, font_handle, video_data,
font_path, font_size, true, FONT_DRIVER_RENDER_CTR);
}
menu_display_ctx_driver_t menu_display_ctx_ctr = {
menu_display_ctr_draw,
menu_display_ctr_draw_pipeline,
menu_display_ctr_viewport,
menu_display_ctr_blend_begin,
menu_display_ctr_blend_end,
menu_display_ctr_restore_clear_color,
menu_display_ctr_clear_color,
menu_display_ctr_get_default_mvp,
menu_display_ctr_get_default_vertices,
menu_display_ctr_get_default_tex_coords,
menu_display_ctr_font_init_first,
MENU_VIDEO_DRIVER_CTR,
"menu_display_ctr",
};

View File

@ -61,6 +61,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = {
#endif
#ifdef HAVE_VITA2D
&menu_display_ctx_vita2d,
#endif
#ifdef _3DS
&menu_display_ctx_ctr,
#endif
&menu_display_ctx_null,
NULL,
@ -113,6 +116,10 @@ static bool menu_display_check_compatibility(
if (string_is_equal(video_driver, "vita2d"))
return true;
break;
case MENU_VIDEO_DRIVER_CTR:
if (string_is_equal(video_driver, "ctr"))
return true;
break;
}
return false;

View File

@ -86,7 +86,8 @@ enum menu_display_driver_type
MENU_VIDEO_DRIVER_OPENGL,
MENU_VIDEO_DRIVER_VULKAN,
MENU_VIDEO_DRIVER_DIRECT3D,
MENU_VIDEO_DRIVER_VITA2D
MENU_VIDEO_DRIVER_VITA2D,
MENU_VIDEO_DRIVER_CTR
};
typedef struct menu_display_ctx_clearcolor
@ -271,6 +272,7 @@ extern menu_display_ctx_driver_t menu_display_ctx_gl;
extern menu_display_ctx_driver_t menu_display_ctx_vulkan;
extern menu_display_ctx_driver_t menu_display_ctx_d3d;
extern menu_display_ctx_driver_t menu_display_ctx_vita2d;
extern menu_display_ctx_driver_t menu_display_ctx_ctr;
extern menu_display_ctx_driver_t menu_display_ctx_null;
RETRO_END_DECLS