Merge pull request #3420 from frangarcj/master

(VITA) Add XMB support
This commit is contained in:
Twinaphex 2016-08-23 09:57:47 +02:00 committed by GitHub
commit f8c70c0c36
27 changed files with 983 additions and 376 deletions

View File

@ -245,7 +245,7 @@ else ifeq ($(platform), vita)
HAVE_NETWORKING := 1 HAVE_NETWORKING := 1
HAVE_NETPLAY := 1 HAVE_NETPLAY := 1
HAVE_OVERLAY := 1 HAVE_OVERLAY := 1
#HAVE_XMB := 1 HAVE_XMB := 1
RARCH_CONSOLE = 1 RARCH_CONSOLE = 1
HAVE_THREADS := 1 HAVE_THREADS := 1
endif endif

0
deps/libvita2d/include/bin_packing_2d.h vendored Normal file → Executable file
View File

0
deps/libvita2d/include/int_htab.h vendored Normal file → Executable file
View File

0
deps/libvita2d/include/shared.h vendored Normal file → Executable file
View File

21
deps/libvita2d/include/texture_atlas.h vendored Normal file → Executable file
View File

@ -9,27 +9,36 @@
extern "C" { extern "C" {
#endif #endif
typedef struct atlas_htab_entry { typedef struct texture_atlas_entry_data {
bp2d_rectangle rect;
int bitmap_left; int bitmap_left;
int bitmap_top; int bitmap_top;
int advance_x; int advance_x;
int advance_y; int advance_y;
int glyph_size; int glyph_size;
} texture_atlas_entry_data;
typedef struct texture_atlas_htab_entry {
bp2d_rectangle rect;
texture_atlas_entry_data data;
} atlas_htab_entry; } atlas_htab_entry;
typedef struct texture_atlas { typedef struct texture_atlas {
vita2d_texture *tex; vita2d_texture *texture;
bp2d_node *bp_root; bp2d_node *bp_root;
int_htab *htab; int_htab *htab;
} texture_atlas; } texture_atlas;
texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat format); texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat format);
void texture_atlas_free(texture_atlas *atlas); void texture_atlas_free(texture_atlas *atlas);
int texture_atlas_insert(texture_atlas *atlas, unsigned int character, int width, int height, int bitmap_left, int bitmap_top, int advance_x, int advance_y, int glyph_size, int *inserted_x, int *inserted_y); int texture_atlas_insert(texture_atlas *atlas, unsigned int character,
int texture_atlas_insert_draw(texture_atlas *atlas, unsigned int character, const void *image, int width, int height, int bitmap_left, int bitmap_top, int advance_x, int advance_y, int glyph_size); const bp2d_size *size,
const texture_atlas_entry_data *data,
bp2d_position *inserted_pos);
int texture_atlas_exists(texture_atlas *atlas, unsigned int character); int texture_atlas_exists(texture_atlas *atlas, unsigned int character);
int texture_atlas_get(texture_atlas *atlas, unsigned int character, bp2d_rectangle *rect, int *bitmap_left, int *bitmap_top, int *advance_x, int *advance_y, int *glyph_size); int texture_atlas_get(texture_atlas *atlas, unsigned int character,
bp2d_rectangle *rect, texture_atlas_entry_data *data);
#ifdef __cplusplus #ifdef __cplusplus
} }

5
deps/libvita2d/include/utils.h vendored Normal file → Executable file
View File

@ -8,6 +8,10 @@
/* Misc utils */ /* Misc utils */
#define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
#define UNUSED(a) (void)(a) #define UNUSED(a) (void)(a)
#define SCREEN_DPI 220
/* Font utils */
uint32_t utf8_character(const char **unicode);
/* GPU utils */ /* GPU utils */
void *gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid); void *gpu_alloc(SceKernelMemBlockType type, unsigned int size, unsigned int alignment, unsigned int attribs, SceUID *uid);
@ -42,5 +46,6 @@ void matrix_init_orthographic(float *m, float left, float right, float bottom, f
void matrix_init_frustum(float *m, float left, float right, float bottom, float top, float near, float far); void matrix_init_frustum(float *m, float left, float right, float bottom, float top, float near, float far);
void matrix_init_perspective(float *m, float fov, float aspect, float near, float far); void matrix_init_perspective(float *m, float fov, float aspect, float near, float far);
/* Text utils */
#endif #endif

View File

@ -42,6 +42,7 @@ typedef struct vita2d_pgf vita2d_pgf;
int vita2d_init(); int vita2d_init();
int vita2d_init_advanced(unsigned int temp_pool_size); int vita2d_init_advanced(unsigned int temp_pool_size);
void vita2d_wait_rendering_done();
int vita2d_fini(); int vita2d_fini();
void vita2d_clear_screen(); void vita2d_clear_screen();
@ -113,7 +114,7 @@ vita2d_font *vita2d_load_font_file(const char *filename);
vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size); vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size);
void vita2d_free_font(vita2d_font *font); void vita2d_free_font(vita2d_font *font);
int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text); int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text);
void vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text, ...); int vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text, ...);
void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size, const char *text, int *width, int *height); void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size, const char *text, int *width, int *height);
int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text); int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text);
int vita2d_font_text_height(vita2d_font *font, unsigned int size, const char *text); int vita2d_font_text_height(vita2d_font *font, unsigned int size, const char *text);
@ -127,6 +128,14 @@ void vita2d_pgf_text_dimensions(vita2d_pgf *font, float scale, const char *text,
int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text); int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text);
int vita2d_pgf_text_height(vita2d_pgf *font, float scale, const char *text); int vita2d_pgf_text_height(vita2d_pgf *font, float scale, const char *text);
/** ADVANCED **/
void vita2d_texture_set_wvp(float x, float y, float width, float height);
void vita2d_texture_set_program();
void vita2d_texture_set_tint_program();
void vita2d_texture_set_tint_color_uniform(unsigned int color);
void vita2d_draw_texture_part_generic(const vita2d_texture *texture, SceGxmPrimitiveType type, vita2d_texture_vertex *vertices, unsigned int num_vertices);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

0
deps/libvita2d/source/bin_packing_2d.c vendored Normal file → Executable file
View File

0
deps/libvita2d/source/int_htab.c vendored Normal file → Executable file
View File

83
deps/libvita2d/source/texture_atlas.c vendored Normal file → Executable file
View File

@ -14,74 +14,56 @@ texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat f
rect.w = width; rect.w = width;
rect.h = height; rect.h = height;
atlas->tex = vita2d_create_empty_texture_format(width, height, format); atlas->texture = vita2d_create_empty_texture_format(width,
height,
format);
if (!atlas->texture) {
free(atlas);
return NULL;
}
atlas->bp_root = bp2d_create(&rect); atlas->bp_root = bp2d_create(&rect);
atlas->htab = int_htab_create(256); atlas->htab = int_htab_create(256);
vita2d_texture_set_filters(atlas->tex, SCE_GXM_TEXTURE_FILTER_LINEAR, SCE_GXM_TEXTURE_FILTER_LINEAR); vita2d_texture_set_filters(atlas->texture,
SCE_GXM_TEXTURE_FILTER_POINT,
SCE_GXM_TEXTURE_FILTER_LINEAR);
return atlas; return atlas;
} }
void texture_atlas_free(texture_atlas *atlas) void texture_atlas_free(texture_atlas *atlas)
{ {
vita2d_free_texture(atlas->tex); vita2d_free_texture(atlas->texture);
bp2d_free(atlas->bp_root); bp2d_free(atlas->bp_root);
int_htab_free(atlas->htab); int_htab_free(atlas->htab);
free(atlas); free(atlas);
} }
int texture_atlas_insert(texture_atlas *atlas, unsigned int character, int width, int height, int bitmap_left, int bitmap_top, int advance_x, int advance_y, int glyph_size, int *inserted_x, int *inserted_y) int texture_atlas_insert(texture_atlas *atlas, unsigned int character,
const bp2d_size *size,
const texture_atlas_entry_data *data,
bp2d_position *inserted_pos)
{ {
bp2d_size size; atlas_htab_entry *entry;
size.w = width;
size.h = height;
bp2d_position pos;
bp2d_node *new_node; bp2d_node *new_node;
if (!bp2d_insert(atlas->bp_root, &size, &pos, &new_node))
if (!bp2d_insert(atlas->bp_root, size, inserted_pos, &new_node))
return 0; return 0;
atlas_htab_entry *entry = malloc(sizeof(*entry)); entry = malloc(sizeof(*entry));
entry->rect.x = pos.x; entry->rect.x = inserted_pos->x;
entry->rect.y = pos.y; entry->rect.y = inserted_pos->y;
entry->rect.w = width; entry->rect.w = size->w;
entry->rect.h = height; entry->rect.h = size->h;
entry->bitmap_left = bitmap_left; entry->data = *data;
entry->bitmap_top = bitmap_top;
entry->advance_x = advance_x;
entry->advance_y = advance_y;
entry->glyph_size = glyph_size;
if (!int_htab_insert(atlas->htab, character, entry)) { if (!int_htab_insert(atlas->htab, character, entry)) {
bp2d_delete(atlas->bp_root, new_node); bp2d_delete(atlas->bp_root, new_node);
return 0; return 0;
} }
if (inserted_x)
*inserted_x = pos.x;
if (inserted_y)
*inserted_y = pos.y;
return 1;
}
int texture_atlas_insert_draw(texture_atlas *atlas, unsigned int character, const void *image, int width, int height, int bitmap_left, int bitmap_top, int advance_x, int advance_y, int glyph_size)
{
int pos_x;
int pos_y;
if (!texture_atlas_insert(atlas, character, width, height, bitmap_left, bitmap_top, advance_x, advance_y, glyph_size, &pos_x, &pos_y))
return 0;
void *tex_data = vita2d_texture_get_datap(atlas->tex);
unsigned int tex_width = vita2d_texture_get_width(atlas->tex);
int i;
for (i = 0; i < height; i++) {
memcpy(tex_data + (pos_x + (pos_y + i)*tex_width), image + i*width, width);
}
return 1; return 1;
} }
@ -90,22 +72,15 @@ int texture_atlas_exists(texture_atlas *atlas, unsigned int character)
return int_htab_find(atlas->htab, character) != NULL; return int_htab_find(atlas->htab, character) != NULL;
} }
int texture_atlas_get(texture_atlas *atlas, unsigned int character, bp2d_rectangle *rect, int *bitmap_left, int *bitmap_top, int *advance_x, int *advance_y, int *glyph_size) int texture_atlas_get(texture_atlas *atlas, unsigned int character,
bp2d_rectangle *rect, texture_atlas_entry_data *data)
{ {
atlas_htab_entry *entry = int_htab_find(atlas->htab, character); atlas_htab_entry *entry = int_htab_find(atlas->htab, character);
if (!entry) if (!entry)
return 0; return 0;
rect->x = entry->rect.x; *rect = entry->rect;
rect->y = entry->rect.y; *data = entry->data;
rect->w = entry->rect.w;
rect->h = entry->rect.h;
*bitmap_left = entry->bitmap_left;
*bitmap_top = entry->bitmap_top;
*advance_x = entry->advance_x;
*advance_y = entry->advance_y;
if (glyph_size)
*glyph_size = entry->glyph_size;
return 1; return 1;
} }

33
deps/libvita2d/source/utils.c vendored Normal file → Executable file
View File

@ -267,3 +267,36 @@ void matrix_init_perspective(float *m, float fov, float aspect, float near, floa
matrix_init_frustum(m, -half_width, half_width, -half_height, half_height, near, far); matrix_init_frustum(m, -half_width, half_width, -half_height, half_height, near, far);
} }
uint32_t utf8_character(const char** unicode)
{
char byte = **unicode;
++*unicode;
if (!(byte & 0x80)) {
return byte;
}
uint32_t unichar;
const static int tops[4] = { 0xC0, 0xE0, 0xF0, 0xF8 };
size_t numBytes;
for (numBytes = 0; numBytes < 3; ++numBytes) {
if ((byte & tops[numBytes + 1]) == tops[numBytes]) {
break;
}
}
unichar = byte & ~tops[numBytes];
if (numBytes == 3) {
return 0;
}
++numBytes;
size_t i;
for (i = 0; i < numBytes; ++i) {
unichar <<= 6;
byte = **unicode;
++*unicode;
if ((byte & 0xC0) != 0x80) {
return 0;
}
unichar |= byte & 0x3F;
}
return unichar;
}

11
deps/libvita2d/source/vita2d.c vendored Normal file → Executable file
View File

@ -584,7 +584,7 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
// Allocate memory for the memory pool // Allocate memory for the memory pool
pool_size = temp_pool_size; pool_size = temp_pool_size;
pool_addr = gpu_alloc( pool_addr = gpu_alloc(
SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, SCE_KERNEL_MEMBLOCK_TYPE_USER_RW,
pool_size, pool_size,
sizeof(void *), sizeof(void *),
SCE_GXM_MEMORY_ATTRIB_READ, SCE_GXM_MEMORY_ATTRIB_READ,
@ -604,6 +604,11 @@ int vita2d_init_advanced(unsigned int temp_pool_size)
return 1; return 1;
} }
void vita2d_wait_rendering_done()
{
sceGxmFinish(_vita2d_context);
}
int vita2d_fini() int vita2d_fini()
{ {
unsigned int i; unsigned int i;
@ -674,8 +679,8 @@ int vita2d_fini()
// terminate libgxm // terminate libgxm
sceGxmTerminate(); sceGxmTerminate();
if (pgf_module_was_loaded != SCE_SYSMODULE_LOADED) /* if (pgf_module_was_loaded != SCE_SYSMODULE_LOADED)
sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF); sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF); */
vita2d_initialized = 0; vita2d_initialized = 0;

0
deps/libvita2d/source/vita2d_draw.c vendored Normal file → Executable file
View File

283
deps/libvita2d/source/vita2d_font.c vendored Normal file → Executable file
View File

@ -11,16 +11,16 @@
#include "utils.h" #include "utils.h"
#include "shared.h" #include "shared.h"
#define ATLAS_DEFAULT_W 256 #define ATLAS_DEFAULT_W 512
#define ATLAS_DEFAULT_H 256 #define ATLAS_DEFAULT_H 512
typedef enum { typedef enum {
VITA2D_LOAD_FROM_FILE, VITA2D_LOAD_FONT_FROM_FILE,
VITA2D_LOAD_FROM_MEM VITA2D_LOAD_FONT_FROM_MEM
} vita2d_font_load_from; } vita2d_load_font_from;
typedef struct vita2d_font { typedef struct vita2d_font {
vita2d_font_load_from load_from; vita2d_load_font_from load_from;
union { union {
char *filename; char *filename;
struct { struct {
@ -32,22 +32,23 @@ typedef struct vita2d_font {
FTC_Manager ftcmanager; FTC_Manager ftcmanager;
FTC_CMapCache cmapcache; FTC_CMapCache cmapcache;
FTC_ImageCache imagecache; FTC_ImageCache imagecache;
texture_atlas *tex_atlas; texture_atlas *atlas;
} vita2d_font; } vita2d_font;
static FT_Error ftc_face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face) static FT_Error ftc_face_requester(FTC_FaceID face_id, FT_Library library,
FT_Pointer request_data, FT_Face *face)
{ {
vita2d_font *font = (vita2d_font *)face_id; vita2d_font *font = (vita2d_font *)face_id;
FT_Error error = FT_Err_Cannot_Open_Resource; FT_Error error = FT_Err_Cannot_Open_Resource;
if (font->load_from == VITA2D_LOAD_FROM_FILE) { if (font->load_from == VITA2D_LOAD_FONT_FROM_FILE) {
error = FT_New_Face( error = FT_New_Face(
font->ftlibrary, font->ftlibrary,
font->filename, font->filename,
0, 0,
face); face);
} else if (font->load_from == VITA2D_LOAD_FROM_MEM) { } else if (font->load_from == VITA2D_LOAD_FONT_FROM_MEM) {
error = FT_New_Memory_Face( error = FT_New_Memory_Face(
font->ftlibrary, font->ftlibrary,
font->font_buffer, font->font_buffer,
@ -82,21 +83,19 @@ vita2d_font *vita2d_load_font_file(const char *filename)
&font->ftcmanager); &font->ftcmanager);
if (error != FT_Err_Ok) { if (error != FT_Err_Ok) {
free(font);
FT_Done_FreeType(font->ftlibrary); FT_Done_FreeType(font->ftlibrary);
free(font);
return NULL; return NULL;
} }
size_t len = strlen(filename); font->filename = strdup(filename);
font->filename = malloc(len + 1);
strcpy(font->filename, filename);
FTC_CMapCache_New(font->ftcmanager, &font->cmapcache); FTC_CMapCache_New(font->ftcmanager, &font->cmapcache);
FTC_ImageCache_New(font->ftcmanager, &font->imagecache); FTC_ImageCache_New(font->ftcmanager, &font->imagecache);
font->load_from = VITA2D_LOAD_FROM_FILE; font->load_from = VITA2D_LOAD_FONT_FROM_FILE;
font->tex_atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H, font->atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H,
SCE_GXM_TEXTURE_FORMAT_U8_R111); SCE_GXM_TEXTURE_FORMAT_U8_R111);
return font; return font;
@ -126,8 +125,8 @@ vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size)
&font->ftcmanager); &font->ftcmanager);
if (error != FT_Err_Ok) { if (error != FT_Err_Ok) {
free(font);
FT_Done_FreeType(font->ftlibrary); FT_Done_FreeType(font->ftlibrary);
free(font);
return NULL; return NULL;
} }
@ -137,9 +136,9 @@ vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size)
FTC_CMapCache_New(font->ftcmanager, &font->cmapcache); FTC_CMapCache_New(font->ftcmanager, &font->cmapcache);
FTC_ImageCache_New(font->ftcmanager, &font->imagecache); FTC_ImageCache_New(font->ftcmanager, &font->imagecache);
font->load_from = VITA2D_LOAD_FROM_MEM; font->load_from = VITA2D_LOAD_FONT_FROM_MEM;
font->tex_atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H, font->atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H,
SCE_GXM_TEXTURE_FORMAT_U8_R111); SCE_GXM_TEXTURE_FORMAT_U8_R111);
return font; return font;
@ -151,60 +150,91 @@ void vita2d_free_font(vita2d_font *font)
FTC_FaceID face_id = (FTC_FaceID)font; FTC_FaceID face_id = (FTC_FaceID)font;
FTC_Manager_RemoveFaceID(font->ftcmanager, face_id); FTC_Manager_RemoveFaceID(font->ftcmanager, face_id);
FTC_Manager_Done(font->ftcmanager); FTC_Manager_Done(font->ftcmanager);
if (font->load_from == VITA2D_LOAD_FROM_FILE) { if (font->load_from == VITA2D_LOAD_FONT_FROM_FILE) {
free(font->filename); free(font->filename);
} }
texture_atlas_free(font->tex_atlas); texture_atlas_free(font->atlas);
free(font); free(font);
} }
} }
static int atlas_add_glyph(texture_atlas *atlas, unsigned int glyph_index, const FT_BitmapGlyph bitmap_glyph, int glyph_size) static int atlas_add_glyph(texture_atlas *atlas, unsigned int glyph_index,
const FT_BitmapGlyph bitmap_glyph, int glyph_size)
{ {
int ret;
int i, j;
bp2d_position position;
void *texture_data;
unsigned int tex_width;
const FT_Bitmap *bitmap = &bitmap_glyph->bitmap; const FT_Bitmap *bitmap = &bitmap_glyph->bitmap;
unsigned char *buffer = malloc(bitmap->width * bitmap->rows);
unsigned int w = bitmap->width; unsigned int w = bitmap->width;
unsigned int h = bitmap->rows; unsigned int h = bitmap->rows;
unsigned char buffer[w * h];
int j, k; bp2d_size size = {
for (j = 0; j < h; j++) { bitmap->width,
for (k = 0; k < w; k++) { bitmap->rows
};
texture_atlas_entry_data data = {
bitmap_glyph->left,
bitmap_glyph->top,
bitmap_glyph->root.advance.x,
bitmap_glyph->root.advance.y,
glyph_size
};
ret = texture_atlas_insert(atlas, glyph_index, &size, &data,
&position);
if (!ret)
return 0;
for (i = 0; i < h; i++) {
for (j = 0; j < w; j++) {
if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) { if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
buffer[j*w + k] = buffer[i*w + j] =
(bitmap->buffer[j*bitmap->pitch + k/8] & (1 << (7 - k%8))) (bitmap->buffer[i*bitmap->pitch + j/8] & (1 << (7 - j%8)))
? 0xFF : 0; ? 0xFF : 0;
} else { } else if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) {
buffer[j*w + k] = bitmap->buffer[j*bitmap->pitch + k]; buffer[i*w + j] = bitmap->buffer[i*bitmap->pitch + j];
} }
} }
} }
int ret = texture_atlas_insert_draw(atlas, glyph_index, buffer, texture_data = vita2d_texture_get_datap(atlas->texture);
bitmap->width, bitmap->rows, tex_width = vita2d_texture_get_width(atlas->texture);
bitmap_glyph->left, bitmap_glyph->top,
bitmap_glyph->root.advance.x, bitmap_glyph->root.advance.y,
glyph_size);
free(buffer); for (i = 0; i < size.h; i++) {
memcpy(texture_data + (position.x + (position.y + i) * tex_width),
buffer + i * size.w, size.w);
}
return ret; return 1;
} }
int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text) static int generic_font_draw_text(vita2d_font *font, int draw,
int *height, int x, int y,
unsigned int color,
unsigned int size,
const char *text)
{ {
FTC_FaceID face_id = (FTC_FaceID)font; const FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
FT_Face face; FT_Face face;
FTC_Manager_LookupFace(font->ftcmanager, face_id, &face);
FT_Int charmap_index; FT_Int charmap_index;
charmap_index = FT_Get_Charmap_Index(face->charmap);
FT_Glyph glyph; FT_Glyph glyph;
FT_Bool use_kerning = FT_HAS_KERNING(face); FT_UInt glyph_index;
FT_UInt glyph_index, previous = 0; FT_Bool use_kerning;
FTC_FaceID face_id = (FTC_FaceID)font;
FT_UInt previous = 0;
vita2d_texture *tex = font->atlas->texture;
unsigned int character;
int start_x = x;
int max_x = 0;
int pen_x = x; int pen_x = x;
int pen_y = y + size; int pen_y = y;
bp2d_rectangle rect;
texture_atlas_entry_data data;
FTC_ScalerRec scaler; FTC_ScalerRec scaler;
scaler.face_id = face_id; scaler.face_id = face_id;
@ -212,138 +242,101 @@ int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color, u
scaler.height = size; scaler.height = size;
scaler.pixel = 1; scaler.pixel = 1;
FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL; FTC_Manager_LookupFace(font->ftcmanager, face_id, &face);
use_kerning = FT_HAS_KERNING(face);
charmap_index = FT_Get_Charmap_Index(face->charmap);
int max = 0; while (text[0]) {
character = utf8_character(&text);
while (*text) { if (character == '\n') {
if (pen_x > max_x)
if (*text == '\n') { max_x = pen_x;
if ((pen_x - x) > max) pen_x = start_x;
max = pen_x-x;
pen_x = x;
pen_y += size; pen_y += size;
text++;
continue; continue;
} }
glyph_index = FTC_CMapCache_Lookup(font->cmapcache, (FTC_FaceID)font, charmap_index, *text); glyph_index = FTC_CMapCache_Lookup(font->cmapcache,
(FTC_FaceID)font,
charmap_index,
character);
if (use_kerning && previous && glyph_index) { if (use_kerning && previous && glyph_index) {
FT_Vector delta; FT_Vector delta;
FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta); FT_Get_Kerning(face, previous, glyph_index,
FT_KERNING_DEFAULT, &delta);
pen_x += delta.x >> 6; pen_x += delta.x >> 6;
} }
if (!texture_atlas_exists(font->tex_atlas, glyph_index)) { if (!texture_atlas_get(font->atlas, glyph_index, &rect, &data)) {
FTC_ImageCache_LookupScaler(font->imagecache, &scaler, flags, glyph_index, &glyph, NULL); FTC_ImageCache_LookupScaler(font->imagecache,
&scaler,
flags,
glyph_index,
&glyph,
NULL);
if (!atlas_add_glyph(font->tex_atlas, glyph_index, (FT_BitmapGlyph)glyph, size)) { if (!atlas_add_glyph(font->atlas, glyph_index,
(FT_BitmapGlyph)glyph, size)) {
continue; continue;
} }
if (!texture_atlas_get(font->atlas, glyph_index, &rect, &data))
continue;
} }
bp2d_rectangle rect; const float draw_scale = size / (float)data.glyph_size;
int bitmap_left, bitmap_top;
int advance_x, advance_y;
int glyph_size;
if (!texture_atlas_get(font->tex_atlas, glyph_index, if (draw) {
&rect, &bitmap_left, &bitmap_top, vita2d_draw_texture_tint_part_scale(tex,
&advance_x, &advance_y, &glyph_size)) pen_x + data.bitmap_left * draw_scale,
continue; pen_y - data.bitmap_top * draw_scale,
rect.x, rect.y, rect.w, rect.h,
draw_scale,
draw_scale,
color);
}
const float draw_scale = size/(float)glyph_size; pen_x += (data.advance_x >> 16) * draw_scale;
vita2d_draw_texture_tint_part_scale(font->tex_atlas->tex,
pen_x + bitmap_left * draw_scale,
pen_y - bitmap_top * draw_scale,
rect.x, rect.y, rect.w, rect.h,
draw_scale,
draw_scale,
color);
pen_x += (advance_x >> 16) * draw_scale;
pen_y += (advance_y >> 16) * draw_scale;
previous = glyph_index;
text++;
} }
if ((pen_x - x) > max)
max = pen_x-x;
return max; if (pen_x > max_x)
max_x = pen_x;
if (height)
*height = pen_y + size - y;
return max_x - x;
} }
void vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color, unsigned int size, const char *text, ...) int vita2d_font_draw_text(vita2d_font *font, int x, int y, unsigned int color,
unsigned int size, const char *text)
{
return generic_font_draw_text(font, 1, NULL, x, y, color, size, text);
}
int vita2d_font_draw_textf(vita2d_font *font, int x, int y, unsigned int color,
unsigned int size, const char *text, ...)
{ {
char buf[1024]; char buf[1024];
va_list argptr; va_list argptr;
va_start(argptr, text); va_start(argptr, text);
vsnprintf(buf, sizeof(buf), text, argptr); vsnprintf(buf, sizeof(buf), text, argptr);
va_end(argptr); va_end(argptr);
vita2d_font_draw_text(font, x, y, color, size, buf);
return vita2d_font_draw_text(font, x, y, color, size, buf);
} }
void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size, const char *text, int *width, int *height) void vita2d_font_text_dimensions(vita2d_font *font, unsigned int size,
const char *text, int *width, int *height)
{ {
FTC_FaceID face_id = (FTC_FaceID)font; int w;
FT_Face face; w = generic_font_draw_text(font, 0, height, 0, 0, 0, size, text);
FTC_Manager_LookupFace(font->ftcmanager, face_id, &face);
FT_Int charmap_index;
charmap_index = FT_Get_Charmap_Index(face->charmap);
FT_Glyph glyph;
FT_Bool use_kerning = FT_HAS_KERNING(face);
FT_UInt glyph_index, previous = 0;
int pen_x = 0;
int pen_y = size >> 1;
FTC_ScalerRec scaler;
scaler.face_id = face_id;
scaler.width = size;
scaler.height = size;
scaler.pixel = 1;
FT_ULong flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
int max = 0;
while (*text) {
if (*text == '\n') {
if (pen_x > max)
max = pen_x;
pen_x = 0;
pen_y += size;
text++;
continue;
}
glyph_index = FTC_CMapCache_Lookup(font->cmapcache, (FTC_FaceID)font, charmap_index, *text);
if (use_kerning && previous && glyph_index) {
FT_Vector delta;
FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
pen_x += delta.x >> 6;
}
FTC_ImageCache_LookupScaler(font->imagecache, &scaler, flags, glyph_index, &glyph, NULL);
const FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
pen_x += bitmap_glyph->root.advance.x >> 16;
//pen_y += bitmap_glyph->root.advance.y >> 16;
previous = glyph_index;
text++;
}
if(pen_x > max)
max = pen_x;
if (width) if (width)
*width = max; *width = w;
if (height)
*height = size + pen_y;
} }
int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text) int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text)

0
deps/libvita2d/source/vita2d_image_bmp.c vendored Normal file → Executable file
View File

0
deps/libvita2d/source/vita2d_image_jpeg.c vendored Normal file → Executable file
View File

0
deps/libvita2d/source/vita2d_image_png.c vendored Normal file → Executable file
View File

157
deps/libvita2d/source/vita2d_pgf.c vendored Normal file → Executable file
View File

@ -12,13 +12,14 @@
#include "utils.h" #include "utils.h"
#include "shared.h" #include "shared.h"
#define ATLAS_DEFAULT_W 256 #define ATLAS_DEFAULT_W 512
#define ATLAS_DEFAULT_H 256 #define ATLAS_DEFAULT_H 512
typedef struct vita2d_pgf { typedef struct vita2d_pgf {
SceFontLibHandle lib_handle; SceFontLibHandle lib_handle;
SceFontHandle font_handle; SceFontHandle font_handle;
texture_atlas *tex_atlas; texture_atlas *atlas;
float vsize;
} vita2d_pgf; } vita2d_pgf;
static void *pgf_alloc_func(void *userdata, unsigned int size) static void *pgf_alloc_func(void *userdata, unsigned int size)
@ -34,6 +35,7 @@ static void pgf_free_func(void *userdata, void *p)
vita2d_pgf *vita2d_load_default_pgf() vita2d_pgf *vita2d_load_default_pgf()
{ {
unsigned int error; unsigned int error;
SceFontInfo fontinfo;
vita2d_pgf *font = malloc(sizeof(*font)); vita2d_pgf *font = malloc(sizeof(*font));
if (!font) if (!font)
@ -59,14 +61,18 @@ vita2d_pgf *vita2d_load_default_pgf()
return NULL; return NULL;
} }
font->font_handle = sceFontOpen(font->lib_handle, 1, 0, &error); font->font_handle = sceFontOpen(font->lib_handle, 0, 0, &error);
if (error != 0) { if (error != 0) {
sceFontDoneLib(font->lib_handle); sceFontDoneLib(font->lib_handle);
free(font); free(font);
return NULL; return NULL;
} }
font->tex_atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H, sceFontGetFontInfo(font->font_handle, &fontinfo);
font->vsize = (fontinfo.fontStyle.fontV / fontinfo.fontStyle.fontVRes)
* SCREEN_DPI;
font->atlas = texture_atlas_create(ATLAS_DEFAULT_W, ATLAS_DEFAULT_H,
SCE_GXM_TEXTURE_FORMAT_U8_R111); SCE_GXM_TEXTURE_FORMAT_U8_R111);
return font; return font;
@ -77,7 +83,7 @@ void vita2d_free_pgf(vita2d_pgf *font)
if (font) { if (font) {
sceFontClose(font->font_handle); sceFontClose(font->font_handle);
sceFontDoneLib(font->lib_handle); sceFontDoneLib(font->lib_handle);
texture_atlas_free(font->tex_atlas); texture_atlas_free(font->atlas);
free(font); free(font);
} }
} }
@ -85,71 +91,111 @@ void vita2d_free_pgf(vita2d_pgf *font)
static int atlas_add_glyph_pgf(vita2d_pgf *font, unsigned int character) static int atlas_add_glyph_pgf(vita2d_pgf *font, unsigned int character)
{ {
SceFontCharInfo char_info; SceFontCharInfo char_info;
bp2d_position position;
void *texture_data;
vita2d_texture *tex = font->atlas->texture;
if (sceFontGetCharInfo(font->font_handle, character, &char_info) < 0) if (sceFontGetCharInfo(font->font_handle, character, &char_info) < 0)
return 0; return 0;
int pos_x; bp2d_size size = {
int pos_y; char_info.bitmapWidth,
if (!texture_atlas_insert(font->tex_atlas, character, char_info.bitmapHeight
char_info.bitmapWidth, char_info.bitmapHeight, };
char_info.bitmapLeft, char_info.bitmapTop,
texture_atlas_entry_data data = {
char_info.bitmapLeft,
char_info.bitmapTop,
char_info.sfp26AdvanceH, char_info.sfp26AdvanceH,
char_info.sfp26AdvanceV, char_info.sfp26AdvanceV,
0, &pos_x, &pos_y)) 0
};
if (!texture_atlas_insert(font->atlas, character, &size, &data,
&position))
return 0; return 0;
vita2d_texture *tex = font->tex_atlas->tex; texture_data = vita2d_texture_get_datap(tex);
SceFontGlyphImage glyph_image; SceFontGlyphImage glyph_image;
glyph_image.pixelFormat = SCE_FONT_PIXELFORMAT_8; glyph_image.pixelFormat = SCE_FONT_PIXELFORMAT_8;
glyph_image.xPos64 = pos_x << 6; glyph_image.xPos64 = position.x << 6;
glyph_image.yPos64 = pos_y << 6; glyph_image.yPos64 = position.y << 6;
glyph_image.bufWidth = vita2d_texture_get_width(tex); glyph_image.bufWidth = vita2d_texture_get_width(tex);
glyph_image.bufHeight = vita2d_texture_get_height(tex); glyph_image.bufHeight = vita2d_texture_get_height(tex);
glyph_image.bytesPerLine = vita2d_texture_get_stride(tex); glyph_image.bytesPerLine = vita2d_texture_get_stride(tex);
glyph_image.pad = 0; glyph_image.pad = 0;
glyph_image.bufferPtr = (unsigned int)vita2d_texture_get_datap(tex); glyph_image.bufferPtr = (unsigned int)texture_data;
return sceFontGetCharGlyphImage(font->font_handle, character, &glyph_image) == 0; return sceFontGetCharGlyphImage(font->font_handle, character, &glyph_image) == 0;
} }
int vita2d_pgf_draw_text(vita2d_pgf *font, int x, int y, unsigned int color, float scale, const char *text) int generic_pgf_draw_text(vita2d_pgf *font, int draw, int *height,
int x, int y, unsigned int color, float scale,
const char *text)
{ {
unsigned int character;
bp2d_rectangle rect;
texture_atlas_entry_data data;
vita2d_texture *tex = font->atlas->texture;
int start_x = x;
int max_x = 0;
int pen_x = x; int pen_x = x;
int pen_y = y;
while (*text) { while (*text) {
unsigned int character = *text++; character = utf8_character(&text);
if (!texture_atlas_exists(font->tex_atlas, character)) { if (character == '\n') {
if (pen_x > max_x)
max_x = pen_x;
pen_x = start_x;
pen_y += font->vsize * scale;
continue;
}
if (!texture_atlas_get(font->atlas, character, &rect, &data)) {
if (!atlas_add_glyph_pgf(font, character)) { if (!atlas_add_glyph_pgf(font, character)) {
continue; continue;
} }
if (!texture_atlas_get(font->atlas, character,
&rect, &data))
continue;
} }
bp2d_rectangle rect; if (draw) {
int bitmap_left, bitmap_top; vita2d_draw_texture_tint_part_scale(tex,
int advance_x, advance_y; pen_x + data.bitmap_left * scale,
pen_y - data.bitmap_top * scale,
rect.x, rect.y, rect.w, rect.h,
scale,
scale,
color);
}
if (!texture_atlas_get(font->tex_atlas, character, pen_x += (data.advance_x >> 6) * scale;
&rect, &bitmap_left, &bitmap_top,
&advance_x, &advance_y, NULL))
continue;
vita2d_draw_texture_tint_part_scale(font->tex_atlas->tex,
pen_x + bitmap_left * scale,
y - bitmap_top * scale,
rect.x, rect.y, rect.w, rect.h,
scale,
scale,
color);
pen_x += (advance_x >> 6) * scale;
} }
return pen_x - x; if (pen_x > max_x)
max_x = pen_x;
if (height)
*height = pen_y + font->vsize * scale - y;
return max_x - x;
} }
int vita2d_pgf_draw_textf(vita2d_pgf *font, int x, int y, unsigned int color, float scale, const char *text, ...) int vita2d_pgf_draw_text(vita2d_pgf *font, int x, int y,
unsigned int color, float scale,
const char *text)
{
return generic_pgf_draw_text(font, 1, NULL, x, y, color, scale, text);
}
int vita2d_pgf_draw_textf(vita2d_pgf *font, int x, int y,
unsigned int color, float scale,
const char *text, ...)
{ {
char buf[1024]; char buf[1024];
va_list argptr; va_list argptr;
@ -159,39 +205,14 @@ int vita2d_pgf_draw_textf(vita2d_pgf *font, int x, int y, unsigned int color, fl
return vita2d_pgf_draw_text(font, x, y, color, scale, buf); return vita2d_pgf_draw_text(font, x, y, color, scale, buf);
} }
void vita2d_pgf_text_dimensions(vita2d_pgf *font, float scale, const char *text, int *width, int *height) void vita2d_pgf_text_dimensions(vita2d_pgf *font, float scale,
const char *text, int *width, int *height)
{ {
int pen_x = 0; int w;
int max_h = 0; w = generic_pgf_draw_text(font, 0, height, 0, 0, 0, scale, text);
while (*text) {
unsigned int character = *text++;
if (!texture_atlas_exists(font->tex_atlas, character)) {
if (!atlas_add_glyph_pgf(font, character)) {
continue;
}
}
bp2d_rectangle rect;
int bitmap_left, bitmap_top;
int advance_x, advance_y;
if (!texture_atlas_get(font->tex_atlas, character,
&rect, &bitmap_left, &bitmap_top,
&advance_x, &advance_y, NULL))
continue;
if (rect.h > max_h)
max_h = rect.h;
pen_x += (advance_x >> 6) * scale;
}
if (width) if (width)
*width = pen_x; *width = w;
if (height)
*height = max_h;
} }
int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text) int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text)

View File

@ -178,6 +178,7 @@ static inline void set_texture_wvp_uniform()
{ {
void *vertex_wvp_buffer; void *vertex_wvp_buffer;
sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer); sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer);
//matrix_init_orthographic(_vita2d_ortho_matrix, 0.0f, DISPLAY_WIDTH, DISPLAY_HEIGHT, 0.0f, 0.0f, 1.0f);
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix); sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix);
} }
@ -648,3 +649,44 @@ void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float
rad, vita2d_texture_get_width(texture)/2.0f, rad, vita2d_texture_get_width(texture)/2.0f,
vita2d_texture_get_height(texture)/2.0f, color); vita2d_texture_get_height(texture)/2.0f, color);
} }
void vita2d_texture_set_wvp(float x, float y, float width, float height)
{
void *vertex_wvp_buffer;
matrix_init_orthographic(_vita2d_ortho_matrix, x, width, height, y, 0.0f, 1.0f);
sceGxmReserveVertexDefaultUniformBuffer(_vita2d_context, &vertex_wvp_buffer);
sceGxmSetUniformDataF(vertex_wvp_buffer, _vita2d_textureWvpParam, 0, 16, _vita2d_ortho_matrix);
}
void vita2d_texture_set_program(){
set_texture_program();
}
void vita2d_texture_set_tint_program(){
set_texture_tint_program();
}
void vita2d_texture_set_tint_color_uniform(unsigned int color){
set_texture_tint_color_uniform(color);
}
void vita2d_draw_texture_part_generic(const vita2d_texture *texture, SceGxmPrimitiveType type, vita2d_texture_vertex *vertices, unsigned int num_vertices)
{
uint16_t *indices = (uint16_t *)vita2d_pool_memalign(
num_vertices * sizeof(uint16_t), // 4 indices
sizeof(uint16_t));
for(int n = 0; n < num_vertices; n++){
indices[n] = n;
}
// Set the texture to the TEXUNIT0
sceGxmSetFragmentTexture(_vita2d_context, 0, &texture->gxm_tex);
sceGxmSetVertexStream(_vita2d_context, 0, vertices);
sceGxmDraw(_vita2d_context, type, SCE_GXM_INDEX_FORMAT_U16, indices, 4);
}

View File

@ -0,0 +1,88 @@
/* 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/>.
*/
#ifndef VITA2D_COMMON_H__
#define VITA2D_COMMON_H__
#include <vita2d.h>
#include <retro_inline.h>
#include <string/stdstring.h>
#include "../../defines/psp_defines.h"
#include "../../general.h"
#include "../../driver.h"
#include "../video_coord_array.h"
typedef struct vita_menu_frame
{
bool active;
int width;
int height;
vita2d_texture *texture;
} vita_menu_t;
#ifdef HAVE_OVERLAY
struct vita_overlay_data
{
vita2d_texture *tex;
float x;
float y;
float w;
float h;
float tex_x;
float tex_y;
float tex_w;
float tex_h;
float alpha_mod;
float width;
float height;
};
#endif
typedef struct vita_video
{
vita2d_texture *texture;
SceGxmTextureFormat format;
int width;
int height;
SceGxmTextureFilter tex_filter;
bool fullscreen;
bool vsync;
bool rgb32;
video_viewport_t vp;
unsigned rotation;
math_matrix_4x4 mvp, mvp_no_rot;
bool vblank_not_reached;
bool keep_aspect;
bool should_resize;
vita_menu_t menu;
#ifdef HAVE_OVERLAY
struct vita_overlay_data *overlay;
unsigned overlays;
bool overlay_enable;
bool overlay_full_screen;
#endif
} vita_video_t;
#endif

View File

@ -20,70 +20,25 @@
#include <string/stdstring.h> #include <string/stdstring.h>
#include "../../defines/psp_defines.h" #include "../../defines/psp_defines.h"
#include "../common/vita2d_common.h"
#include "../../general.h" #include "../../general.h"
#include "../../driver.h" #include "../../driver.h"
#include "../video_coord_array.h"
typedef struct vita_menu_frame #ifdef HAVE_MENU
{ #include "../../menu/menu_driver.h"
bool active;
int width;
int height;
vita2d_texture *texture;
} vita_menu_t;
#ifdef HAVE_OVERLAY
struct vita_overlay_data
{
vita2d_texture *tex;
float x;
float y;
float w;
float h;
float tex_x;
float tex_y;
float tex_w;
float tex_h;
float alpha_mod;
float width;
float height;
};
#endif #endif
typedef struct vita_video static void vita2d_gfx_set_viewport(void *data, unsigned viewport_width,
{ unsigned viewport_height, bool force_full, bool allow_rotate);
vita2d_texture *texture;
SceGxmTextureFormat format;
int width;
int height;
SceGxmTextureFilter tex_filter;
bool fullscreen;
bool vsync;
bool rgb32;
video_viewport_t vp;
unsigned rotation;
bool vblank_not_reached;
bool keep_aspect;
bool should_resize;
vita_menu_t menu;
#ifdef HAVE_OVERLAY
struct vita_overlay_data *overlay;
unsigned overlays;
bool overlay_enable;
bool overlay_full_screen;
#endif
} vita_video_t;
static void *vita2d_gfx_init(const video_info_t *video, static void *vita2d_gfx_init(const video_info_t *video,
const input_driver_t **input, void **input_data) const input_driver_t **input, void **input_data)
{ {
vita_video_t *vita = (vita_video_t *)calloc(1, sizeof(vita_video_t)); vita_video_t *vita = (vita_video_t *)calloc(1, sizeof(vita_video_t));
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
unsigned temp_width = PSP_FB_WIDTH;
unsigned temp_height = PSP_FB_HEIGHT;
if (!vita) if (!vita)
return NULL; return NULL;
@ -124,6 +79,10 @@ static void *vita2d_gfx_init(const video_info_t *video,
vita->tex_filter = video->smooth vita->tex_filter = video->smooth
? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT; ? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT;
video_driver_set_size(&temp_width, &temp_height);
vita2d_gfx_set_viewport(vita, temp_width, temp_height, false, true);
if (input && input_data) if (input && input_data)
{ {
void *pspinput = input_psp.init(); void *pspinput = input_psp.init();
@ -260,34 +219,42 @@ static bool vita2d_gfx_frame(void *data, const void *frame,
vita2d_render_overlay(vita); vita2d_render_overlay(vita);
#endif #endif
if (vita->menu.active && vita->menu.texture) if (vita->menu.active)
{ {
if (vita->fullscreen)
vita2d_draw_texture_scale(vita->menu.texture, if(vita->menu.texture){
0, 0, if (vita->fullscreen)
PSP_FB_WIDTH / (float)vita->menu.width, vita2d_draw_texture_scale(vita->menu.texture,
PSP_FB_HEIGHT / (float)vita->menu.height); 0, 0,
else PSP_FB_WIDTH / (float)vita->menu.width,
{ PSP_FB_HEIGHT / (float)vita->menu.height);
if (vita->menu.width > vita->menu.height) else
{ {
float scale = PSP_FB_HEIGHT / (float)vita->menu.height; if (vita->menu.width > vita->menu.height)
float w = vita->menu.width * scale; {
vita2d_draw_texture_scale(vita->menu.texture, float scale = PSP_FB_HEIGHT / (float)vita->menu.height;
PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f, float w = vita->menu.width * scale;
scale, scale); vita2d_draw_texture_scale(vita->menu.texture,
} PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f,
else scale, scale);
{ }
float scale = PSP_FB_WIDTH / (float)vita->menu.width; else
float h = vita->menu.height * scale; {
vita2d_draw_texture_scale(vita->menu.texture, float scale = PSP_FB_WIDTH / (float)vita->menu.width;
0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f, float h = vita->menu.height * scale;
scale, scale); vita2d_draw_texture_scale(vita->menu.texture,
} 0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f,
} scale, scale);
}
}
}
menu_driver_ctl(RARCH_MENU_CTL_FRAME, NULL);
} }
if(!string_is_empty(msg)) if(!string_is_empty(msg))
font_driver_render_msg(NULL, msg, NULL); font_driver_render_msg(NULL, msg, NULL);
@ -366,6 +333,25 @@ static bool vita2d_gfx_set_shader(void *data,
return false; return false;
} }
static void vita2d_set_projection(vita_video_t *vita,
struct video_ortho *ortho, bool allow_rotate)
{
math_matrix_4x4 rot;
/* Calculate projection. */
matrix_4x4_ortho(&vita->mvp_no_rot, ortho->left, ortho->right,
ortho->bottom, ortho->top, ortho->znear, ortho->zfar);
if (!allow_rotate)
{
vita->mvp = vita->mvp_no_rot;
return;
}
matrix_4x4_rotate_z(&rot, M_PI * vita->rotation / 180.0f);
matrix_4x4_multiply(&vita->mvp, &rot, &vita->mvp_no_rot);
}
static void vita2d_gfx_update_viewport(vita_video_t* vita) static void vita2d_gfx_update_viewport(vita_video_t* vita)
{ {
int x = 0; int x = 0;
@ -457,6 +443,110 @@ static void vita2d_gfx_update_viewport(vita_video_t* vita)
} }
static void vita2d_gfx_set_viewport(void *data, unsigned viewport_width,
unsigned viewport_height, bool force_full, bool allow_rotate)
{
gfx_ctx_aspect_t aspect_data;
unsigned width, height;
int x = 0;
int y = 0;
float device_aspect = (float)viewport_width / viewport_height;
struct video_ortho ortho = {0, 1, 1, 0, -1, 1};
settings_t *settings = config_get_ptr();
vita_video_t *vita = (vita_video_t*)data;
video_driver_get_size(&width, &height);
aspect_data.aspect = &device_aspect;
aspect_data.width = viewport_width;
aspect_data.height = viewport_height;
video_context_driver_translate_aspect(&aspect_data);
if (settings->video.scale_integer && !force_full)
{
video_viewport_get_scaled_integer(&vita->vp,
viewport_width, viewport_height,
video_driver_get_aspect_ratio(), vita->keep_aspect);
viewport_width = vita->vp.width;
viewport_height = vita->vp.height;
}
else if (vita->keep_aspect && !force_full)
{
float desired_aspect = video_driver_get_aspect_ratio();
#if defined(HAVE_MENU)
if (settings->video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM)
{
const struct video_viewport *custom = video_viewport_get_custom();
/* Vukan has top-left origin viewport. */
x = custom->x;
y = custom->y;
viewport_width = custom->width;
viewport_height = custom->height;
}
else
#endif
{
float delta;
if (fabsf(device_aspect - desired_aspect) < 0.0001f)
{
/* If the aspect ratios of screen and desired aspect
* ratio are sufficiently equal (floating point stuff),
* assume they are actually equal.
*/
}
else if (device_aspect > desired_aspect)
{
delta = (desired_aspect / device_aspect - 1.0f)
/ 2.0f + 0.5f;
x = (int)roundf(viewport_width * (0.5f - delta));
viewport_width = (unsigned)roundf(2.0f * viewport_width * delta);
}
else
{
delta = (device_aspect / desired_aspect - 1.0f)
/ 2.0f + 0.5f;
y = (int)roundf(viewport_height * (0.5f - delta));
viewport_height = (unsigned)roundf(2.0f * viewport_height * delta);
}
}
vita->vp.x = x;
vita->vp.y = y;
vita->vp.width = viewport_width;
vita->vp.height = viewport_height;
}
else
{
vita->vp.x = 0;
vita->vp.y = 0;
vita->vp.width = viewport_width;
vita->vp.height = viewport_height;
}
vita2d_set_projection(vita, &ortho, allow_rotate);
/* Set last backbuffer viewport. */
if (!force_full)
{
vita->vp.width = viewport_width;
vita->vp.height = viewport_height;
}
/*vita->vp.x = (float)vita->vp.x;
vita->vp.y = (float)vita->vp.y;
vita->vp.width = (float)vita->vp.width;
vita->vp.height = (float)vita->vp.height;
vita->vp.minDepth = 0.0f;
vita->vp.maxDepth = 1.0f;*/
RARCH_LOG("Setting viewport @ %ux%u\n", viewport_width, viewport_height);
}
static void vita2d_gfx_set_rotation(void *data, static void vita2d_gfx_set_rotation(void *data,
unsigned rotation) unsigned rotation)
{ {
@ -603,9 +693,57 @@ static void vita_set_texture_enable(void *data, bool state, bool full_screen)
vita->menu.active = state; vita->menu.active = state;
} }
static uintptr_t vita_load_texture(void *video_data, void *data,
bool threaded, enum texture_filter_type filter_type)
{
unsigned int stride, pitch, j, k;
struct texture_image *image = (struct texture_image*)data;
struct vita2d_texture *texture = vita2d_create_empty_texture_format(image->width,
image->height,SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB);
if (!texture)
return 0;
RARCH_LOG("%d %d \n",image->height,image->width);
if(filter_type == TEXTURE_FILTER_MIPMAP_LINEAR ||
filter_type == TEXTURE_FILTER_LINEAR)
vita2d_texture_set_filters(texture,SCE_GXM_TEXTURE_FILTER_LINEAR,SCE_GXM_TEXTURE_FILTER_LINEAR);
stride = vita2d_texture_get_stride(texture);
stride /= 4;
uint32_t *tex32 = vita2d_texture_get_datap(texture);
const uint32_t *frame32 = image->pixels;
pitch = image->width;
for (j = 0; j < image->height; j++)
for (k = 0; k < image->width; k++)
tex32[k + j*stride] = frame32[k + j*pitch];
return (uintptr_t)texture;
}
static void vita_unload_texture(void *data, uintptr_t handle)
{
struct vita2d_texture *texture = (struct vita2d_texture*)handle;
if (!texture)
return;
/* TODO: We really want to defer this deletion instead,
* but this will do for now. */
vita2d_wait_rendering_done();
vita2d_free_texture(texture);
//free(texture);
}
static void vita_set_osd_msg(void *data, const char *msg,
const struct font_params *params, void *font)
{
(void)data;
font_driver_render_msg(font, msg, params);
}
static const video_poke_interface_t vita_poke_interface = { static const video_poke_interface_t vita_poke_interface = {
NULL, vita_load_texture,
NULL, vita_unload_texture,
NULL, NULL,
vita_set_filtering, vita_set_filtering,
NULL, /* get_video_output_size */ NULL, /* get_video_output_size */
@ -618,10 +756,18 @@ static const video_poke_interface_t vita_poke_interface = {
#ifdef HAVE_MENU #ifdef HAVE_MENU
vita_set_texture_frame, vita_set_texture_frame,
vita_set_texture_enable, vita_set_texture_enable,
#endif #else
NULL, NULL,
NULL, NULL,
NULL #endif
#ifdef HAVE_MENU
vita_set_osd_msg,
#endif
NULL,
NULL,
NULL,
NULL,
NULL,
}; };
static void vita2d_gfx_get_poke_interface(void *data, static void vita2d_gfx_get_poke_interface(void *data,
@ -779,7 +925,7 @@ video_driver_t video_vita2d = {
vita2d_gfx_set_shader, vita2d_gfx_set_shader,
vita2d_gfx_free, vita2d_gfx_free,
"vita2d", "vita2d",
NULL, /* set_viewport */ vita2d_gfx_set_viewport,
vita2d_gfx_set_rotation, vita2d_gfx_set_rotation,
vita2d_gfx_viewport_info, vita2d_gfx_viewport_info,
vita2d_gfx_read_viewport, vita2d_gfx_read_viewport,

View File

@ -10701,29 +10701,51 @@ static void vita2d_font_free_font(void *data)
RARCH_LOG("vita2d_font_free()\n"); RARCH_LOG("vita2d_font_free()\n");
} }
static int vita2d_font_get_message_width(void *data, const char *msg,
unsigned msg_len, float scale)
{
vita_font_t *vita = (vita_font_t *)data;
return vita2d_font_text_width(vita->font, vita->size*scale, msg) * scale ;
}
static void vita2d_font_render_msg(void *data, const char *msg, static void vita2d_font_render_msg(void *data, const char *msg,
const void *userdata) const void *userdata)
{ {
float x, y, scale; float x, y, scale;
unsigned color; unsigned color;
unsigned width, height, text_height;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
vita_font_t *vita = (vita_font_t *)data; vita_font_t *vita = (vita_font_t *)data;
const struct font_params *params = (const struct font_params*)userdata; const struct font_params *params = (const struct font_params*)userdata;
(void)data; (void)data;
video_driver_get_size(&width, &height);
if (params) if (params)
{ {
x = params->x; scale = params->scale;
y = params->y; text_height = vita2d_font_text_height(vita->font, vita->size*scale, msg);
scale = params->scale; x = params->x*width;
y = (1-params->y)*height;//-(text_height/4);
color = params->color; color = params->color;
if(params)
switch (params->text_align)
{
case TEXT_ALIGN_RIGHT:
x -= vita2d_font_get_message_width(vita, msg, strlen(msg), scale);
break;
case TEXT_ALIGN_CENTER:
x -= vita2d_font_get_message_width(vita, msg, strlen(msg), scale) / 2.0;
break;
}
} }
else else
{ {
x = settings->video.msg_pos_x; scale = 0.8f;
y = 0.90f; text_height = vita2d_font_text_height(vita->font, vita->size*scale, msg);
scale = 0.8f; x = settings->video.msg_pos_x;
y = text_height;
color = YELLOW; color = YELLOW;
} }
@ -10738,5 +10760,5 @@ font_renderer_t vita2d_vita_font = {
NULL, /* get_glyph */ NULL, /* get_glyph */
NULL, /* bind_block */ NULL, /* bind_block */
NULL, /* flush */ NULL, /* flush */
NULL, /* get_message_width */ vita2d_font_get_message_width,
}; };

View File

@ -918,6 +918,10 @@ MENU
#include "../menu/drivers_display/menu_display_vulkan.c" #include "../menu/drivers_display/menu_display_vulkan.c"
#endif #endif
#ifdef HAVE_VITA2D
#include "../menu/drivers_display/menu_display_vita2d.c"
#endif
#endif #endif
@ -925,8 +929,7 @@ MENU
#include "../menu/drivers/rgui.c" #include "../menu/drivers/rgui.c"
#endif #endif
#ifdef HAVE_OPENGL #if defined(HAVE_OPENGL) || defined(HAVE_VITA2D)
#ifdef HAVE_XMB #ifdef HAVE_XMB
#include "../menu/drivers/xmb.c" #include "../menu/drivers/xmb.c"
#endif #endif

View File

@ -515,8 +515,13 @@ static void xmb_draw_icon(
coords.tex_coord = NULL; coords.tex_coord = NULL;
coords.lut_tex_coord = NULL; coords.lut_tex_coord = NULL;
#if defined(VITA)
draw.width = icon_size*scale_factor;
draw.height = icon_size*scale_factor;
#else
draw.width = icon_size; draw.width = icon_size;
draw.height = icon_size; draw.height = icon_size;
#endif
draw.coords = &coords; draw.coords = &coords;
draw.matrix_data = mymat; draw.matrix_data = mymat;
draw.texture = texture; draw.texture = texture;
@ -533,14 +538,24 @@ static void xmb_draw_icon(
coords.color = shadow; coords.color = shadow;
draw.x = x + shadow_offset; draw.x = x + shadow_offset;
draw.y = height - y - shadow_offset; draw.y = height - y - shadow_offset;
#if defined(VITA)
if(scale_factor<1){
draw.x = draw.x + (icon_size-draw.width)/2;
draw.y = draw.y + (icon_size-draw.width)/2;
}
#endif
menu_display_draw(&draw); menu_display_draw(&draw);
} }
coords.color = (const float*)color; coords.color = (const float*)color;
draw.x = x; draw.x = x;
draw.y = height - y; draw.y = height - y;
#if defined(VITA)
if(scale_factor<1){
draw.x = draw.x + (icon_size-draw.width)/2;
draw.y = draw.y + (icon_size-draw.width)/2;
}
#endif
menu_display_draw(&draw); menu_display_draw(&draw);
} }
@ -1999,6 +2014,8 @@ static void xmb_draw_bg(
menu_display_ctx_draw_t draw; menu_display_ctx_draw_t draw;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
RARCH_LOG("DRAW BG %d %d \n",width,height);
bool running = menu_display_libretro_running(); bool running = menu_display_libretro_running();
draw.x = 0; draw.x = 0;

View File

@ -0,0 +1,228 @@
/* 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>
#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/vita2d_common.h"
#include <vita2d.h>
#include "../menu_display.h"
static const float vita2d_vertexes[] = {
0, 0,
1, 0,
0, 1,
1, 1
};
static const float vita2d_tex_coords[] = {
0, 0,
1, 0,
0, 1,
1, 1
};
static const float *menu_display_vita2d_get_default_vertices(void)
{
RARCH_LOG("DEFAULT VERTICES\n");
return &vita2d_vertexes[0];
}
static const float *menu_display_vita2d_get_default_tex_coords(void)
{
RARCH_LOG("DEFAULT TEX\n");
return &vita2d_tex_coords[0];
}
static void *menu_display_vita2d_get_default_mvp(void)
{
vita_video_t *vita2d = (vita_video_t*)video_driver_get_ptr(false);
if (!vita2d)
return NULL;
return &vita2d->mvp_no_rot;
}
static SceGxmPrimitiveType menu_display_prim_to_vita2d_enum(
enum menu_display_prim_type type)
{
switch (type)
{
case MENU_DISPLAY_PRIM_TRIANGLESTRIP:
return SCE_GXM_PRIMITIVE_TRIANGLE_STRIP;
case MENU_DISPLAY_PRIM_TRIANGLES:
return SCE_GXM_PRIMITIVE_TRIANGLES;
case MENU_DISPLAY_PRIM_NONE:
default:
break;
}
return 0;
}
static void menu_display_vita2d_blend_begin(void)
{
}
static void menu_display_vita2d_blend_end(void)
{
}
static void menu_display_vita2d_viewport(void *data)
{
vita_video_t *vita2d = (vita_video_t*)video_driver_get_ptr(false);
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
if (!vita2d || !draw)
return;
//vita2d_texture_set_wvp(draw->x, draw->y, draw->width, draw->height);
}
static void menu_display_vita2d_draw(void *data)
{
unsigned i;
struct vita2d_texture *texture = NULL;
const float *vertex = NULL;
const float *tex_coord = NULL;
const float *color = NULL;
unsigned int tex_width, tex_height;
vita_video_t *vita2d = (vita_video_t*)video_driver_get_ptr(false);
menu_display_ctx_draw_t *draw = (menu_display_ctx_draw_t*)data;
if (!vita2d || !draw)
return;
texture = (struct vita2d_texture*)draw->texture;
vertex = draw->coords->vertex;
tex_coord = draw->coords->tex_coord;
color = draw->coords->color;
if (!vertex)
vertex = menu_display_vita2d_get_default_vertices();
if (!tex_coord)
tex_coord = menu_display_vita2d_get_default_tex_coords();
if (!draw->coords->lut_tex_coord)
draw->coords->lut_tex_coord = menu_display_vita2d_get_default_tex_coords();
if (!texture)
return;//texture = &vk->display.blank_texture;*/
tex_width = vita2d_texture_get_width(texture);
tex_height = vita2d_texture_get_height(texture);
/*vita2d_texture_set_program();
menu_display_vita2d_viewport(draw);
RARCH_LOG("DRAW BG %d %d \n",draw->width,draw->height);
vita2d_texture_vertex *pv = (vita2d_texture_vertex *)vita2d_pool_memalign(
draw->coords->vertices * sizeof(vita2d_texture_vertex), // 4 vertices
sizeof(vita2d_texture_vertex));
for (i = 0; i < draw->coords->vertices; i++)
{
pv[i].x = *vertex++;
pv[i].y = *vertex++; // Y-flip. Vulkan is top-left clip space
pv[i].z = +0.5f;
pv[i].u = *tex_coord++;
pv[i].v = *tex_coord++;
snprintf(msg, sizeof(msg), "%.2f %.2f %.2f %.2f %.2f\n",pv[i].x,pv[i].y,pv[i].z,pv[i].u,pv[i].v);
RARCH_LOG(msg);
RARCH_LOG("%x %x %x %x %x\n",pv[i].x,pv[i].y,pv[i].z,pv[i].u,pv[i].v);
}*/
switch (draw->pipeline.id)
{
default:
{
int colorR = (int)((*color++)*255.f);
int colorG = (int)((*color++)*255.f);
int colorB = (int)((*color++)*255.f);
int colorA = (int)((*color++)*255.f);
//vita2d_texture_set_tint_color_uniform(RGBA8((int)((*color++)*255.f), (int)((*color++)*255.f), (int)((*color++)*255.f), (int)((*color++)*255.f)));
//vita2d_texture_set_tint_color_uniform(RGBA8(0xFF, 0xFF, 0xFF, 0xAA));
//vita2d_draw_texture_part_generic(texture, menu_display_prim_to_vita2d_enum(
//draw->prim_type), pv, draw->coords->vertices);
vita2d_draw_texture_tint_scale(texture, draw->x,
PSP_FB_HEIGHT-draw->y-draw->height,
(float)draw->width/(float)tex_width,
(float)draw->height/(float)tex_height,
RGBA8(colorR,colorG,colorB,colorA));
//if(texture)vita2d_draw_texture(NULL,0,0);
break;
}
}
}
static void menu_display_vita2d_draw_pipeline(void *data)
{
#ifdef HAVE_SHADERPIPELINE
#endif
}
static void menu_display_vita2d_restore_clear_color(void)
{
vita2d_set_clear_color(RGBA8(0x00, 0x00, 0x00, 0xFF));
}
static void menu_display_vita2d_clear_color(menu_display_ctx_clearcolor_t *clearcolor)
{
if (!clearcolor)
return;
vita2d_set_clear_color(RGBA8((int)(clearcolor->r*255.f),
(int)(clearcolor->g*255.f),
(int)(clearcolor->b*255.f),
(int)(clearcolor->a*255.f)));
vita2d_clear_screen();
}
static bool menu_display_vita2d_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_VITA2D);
}
menu_display_ctx_driver_t menu_display_ctx_vita2d = {
menu_display_vita2d_draw,
menu_display_vita2d_draw_pipeline,
menu_display_vita2d_viewport,
menu_display_vita2d_blend_begin,
menu_display_vita2d_blend_end,
menu_display_vita2d_restore_clear_color,
menu_display_vita2d_clear_color,
menu_display_vita2d_get_default_mvp,
menu_display_vita2d_get_default_vertices,
menu_display_vita2d_get_default_tex_coords,
menu_display_vita2d_font_init_first,
MENU_VIDEO_DRIVER_VITA2D,
"menu_display_vita2d",
};

View File

@ -51,6 +51,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = {
#endif #endif
#ifdef HAVE_VULKAN #ifdef HAVE_VULKAN
&menu_display_ctx_vulkan, &menu_display_ctx_vulkan,
#endif
#ifdef HAVE_VITA2D
&menu_display_ctx_vita2d,
#endif #endif
&menu_display_ctx_null, &menu_display_ctx_null,
NULL, NULL,
@ -89,6 +92,10 @@ static bool menu_display_check_compatibility(
if (string_is_equal(video_driver, "d3d")) if (string_is_equal(video_driver, "d3d"))
return true; return true;
break; break;
case MENU_VIDEO_DRIVER_VITA2D:
if (string_is_equal(video_driver, "vita2d"))
return true;
break;
} }
return false; return false;
@ -548,6 +555,7 @@ void menu_display_draw_gradient(menu_display_ctx_draw_t *draw)
void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw) void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw)
{ {
#if !defined(VITA)
math_matrix_4x4 matrix_rotated, matrix_scaled; math_matrix_4x4 matrix_rotated, matrix_scaled;
math_matrix_4x4 *b = NULL; math_matrix_4x4 *b = NULL;
@ -565,6 +573,7 @@ void menu_display_rotate_z(menu_display_ctx_rotate_draw_t *draw)
matrix_4x4_scale(&matrix_scaled, matrix_4x4_scale(&matrix_scaled,
draw->scale_x, draw->scale_y, draw->scale_z); draw->scale_x, draw->scale_y, draw->scale_z);
matrix_4x4_multiply(draw->matrix, &matrix_scaled, draw->matrix); matrix_4x4_multiply(draw->matrix, &matrix_scaled, draw->matrix);
#endif
} }
bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw) bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw)

View File

@ -85,7 +85,8 @@ enum menu_display_driver_type
MENU_VIDEO_DRIVER_GENERIC = 0, MENU_VIDEO_DRIVER_GENERIC = 0,
MENU_VIDEO_DRIVER_OPENGL, MENU_VIDEO_DRIVER_OPENGL,
MENU_VIDEO_DRIVER_VULKAN, MENU_VIDEO_DRIVER_VULKAN,
MENU_VIDEO_DRIVER_DIRECT3D MENU_VIDEO_DRIVER_DIRECT3D,
MENU_VIDEO_DRIVER_VITA2D
}; };
typedef struct menu_display_ctx_clearcolor typedef struct menu_display_ctx_clearcolor
@ -259,6 +260,7 @@ extern uintptr_t menu_display_white_texture;
extern menu_display_ctx_driver_t menu_display_ctx_gl; 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_vulkan;
extern menu_display_ctx_driver_t menu_display_ctx_d3d; 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_null; extern menu_display_ctx_driver_t menu_display_ctx_null;
RETRO_END_DECLS RETRO_END_DECLS