diff --git a/Makefile.griffin b/Makefile.griffin index ee917a6498..757615f8fb 100644 --- a/Makefile.griffin +++ b/Makefile.griffin @@ -245,7 +245,7 @@ else ifeq ($(platform), vita) HAVE_NETWORKING := 1 HAVE_NETPLAY := 1 HAVE_OVERLAY := 1 - #HAVE_XMB := 1 + HAVE_XMB := 1 RARCH_CONSOLE = 1 HAVE_THREADS := 1 endif diff --git a/deps/libvita2d/include/bin_packing_2d.h b/deps/libvita2d/include/bin_packing_2d.h old mode 100644 new mode 100755 diff --git a/deps/libvita2d/include/int_htab.h b/deps/libvita2d/include/int_htab.h old mode 100644 new mode 100755 diff --git a/deps/libvita2d/include/shared.h b/deps/libvita2d/include/shared.h old mode 100644 new mode 100755 diff --git a/deps/libvita2d/include/texture_atlas.h b/deps/libvita2d/include/texture_atlas.h old mode 100644 new mode 100755 index f0de460daf..87da7862d3 --- a/deps/libvita2d/include/texture_atlas.h +++ b/deps/libvita2d/include/texture_atlas.h @@ -9,27 +9,36 @@ extern "C" { #endif -typedef struct atlas_htab_entry { - bp2d_rectangle rect; +typedef struct texture_atlas_entry_data { int bitmap_left; int bitmap_top; int advance_x; int advance_y; int glyph_size; +} texture_atlas_entry_data; + +typedef struct texture_atlas_htab_entry { + bp2d_rectangle rect; + texture_atlas_entry_data data; } atlas_htab_entry; typedef struct texture_atlas { - vita2d_texture *tex; + vita2d_texture *texture; bp2d_node *bp_root; int_htab *htab; } texture_atlas; texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat format); 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_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 texture_atlas_insert(texture_atlas *atlas, unsigned int character, + 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_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 } diff --git a/deps/libvita2d/include/utils.h b/deps/libvita2d/include/utils.h old mode 100644 new mode 100755 index 53fdabb542..c903a98935 --- a/deps/libvita2d/include/utils.h +++ b/deps/libvita2d/include/utils.h @@ -8,6 +8,10 @@ /* Misc utils */ #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define UNUSED(a) (void)(a) +#define SCREEN_DPI 220 + +/* Font utils */ +uint32_t utf8_character(const char **unicode); /* GPU utils */ 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_perspective(float *m, float fov, float aspect, float near, float far); +/* Text utils */ #endif diff --git a/deps/libvita2d/include/vita2d.h b/deps/libvita2d/include/vita2d.h index f51a8ce2a5..906cb190ae 100644 --- a/deps/libvita2d/include/vita2d.h +++ b/deps/libvita2d/include/vita2d.h @@ -42,6 +42,7 @@ typedef struct vita2d_pgf vita2d_pgf; int vita2d_init(); int vita2d_init_advanced(unsigned int temp_pool_size); +void vita2d_wait_rendering_done(); int vita2d_fini(); 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); 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); -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); 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); @@ -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_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 } #endif diff --git a/deps/libvita2d/source/bin_packing_2d.c b/deps/libvita2d/source/bin_packing_2d.c old mode 100644 new mode 100755 diff --git a/deps/libvita2d/source/int_htab.c b/deps/libvita2d/source/int_htab.c old mode 100644 new mode 100755 diff --git a/deps/libvita2d/source/texture_atlas.c b/deps/libvita2d/source/texture_atlas.c old mode 100644 new mode 100755 index eeb9e0d2e3..6c8b054c44 --- a/deps/libvita2d/source/texture_atlas.c +++ b/deps/libvita2d/source/texture_atlas.c @@ -14,74 +14,56 @@ texture_atlas *texture_atlas_create(int width, int height, SceGxmTextureFormat f rect.w = width; 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->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; } void texture_atlas_free(texture_atlas *atlas) { - vita2d_free_texture(atlas->tex); + vita2d_free_texture(atlas->texture); bp2d_free(atlas->bp_root); int_htab_free(atlas->htab); 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; - size.w = width; - size.h = height; - - bp2d_position pos; + atlas_htab_entry *entry; 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; - atlas_htab_entry *entry = malloc(sizeof(*entry)); + entry = malloc(sizeof(*entry)); - entry->rect.x = pos.x; - entry->rect.y = pos.y; - entry->rect.w = width; - entry->rect.h = height; - entry->bitmap_left = bitmap_left; - entry->bitmap_top = bitmap_top; - entry->advance_x = advance_x; - entry->advance_y = advance_y; - entry->glyph_size = glyph_size; + entry->rect.x = inserted_pos->x; + entry->rect.y = inserted_pos->y; + entry->rect.w = size->w; + entry->rect.h = size->h; + entry->data = *data; if (!int_htab_insert(atlas->htab, character, entry)) { bp2d_delete(atlas->bp_root, new_node); 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; } @@ -90,22 +72,15 @@ int texture_atlas_exists(texture_atlas *atlas, unsigned int character) 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); if (!entry) return 0; - rect->x = entry->rect.x; - rect->y = entry->rect.y; - 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; + *rect = entry->rect; + *data = entry->data; return 1; } diff --git a/deps/libvita2d/source/utils.c b/deps/libvita2d/source/utils.c old mode 100644 new mode 100755 index 2e3fe5d6fa..b87a5ae7ef --- a/deps/libvita2d/source/utils.c +++ b/deps/libvita2d/source/utils.c @@ -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); } + +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; +} diff --git a/deps/libvita2d/source/vita2d.c b/deps/libvita2d/source/vita2d.c old mode 100644 new mode 100755 index 997b89eff1..14658ef545 --- a/deps/libvita2d/source/vita2d.c +++ b/deps/libvita2d/source/vita2d.c @@ -584,7 +584,7 @@ int vita2d_init_advanced(unsigned int temp_pool_size) // Allocate memory for the memory pool pool_size = temp_pool_size; pool_addr = gpu_alloc( - SCE_KERNEL_MEMBLOCK_TYPE_USER_RW_UNCACHE, + SCE_KERNEL_MEMBLOCK_TYPE_USER_RW, pool_size, sizeof(void *), SCE_GXM_MEMORY_ATTRIB_READ, @@ -604,6 +604,11 @@ int vita2d_init_advanced(unsigned int temp_pool_size) return 1; } +void vita2d_wait_rendering_done() +{ + sceGxmFinish(_vita2d_context); +} + int vita2d_fini() { unsigned int i; @@ -674,8 +679,8 @@ int vita2d_fini() // terminate libgxm sceGxmTerminate(); - if (pgf_module_was_loaded != SCE_SYSMODULE_LOADED) - sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF); + /* if (pgf_module_was_loaded != SCE_SYSMODULE_LOADED) + sceSysmoduleUnloadModule(SCE_SYSMODULE_PGF); */ vita2d_initialized = 0; diff --git a/deps/libvita2d/source/vita2d_draw.c b/deps/libvita2d/source/vita2d_draw.c old mode 100644 new mode 100755 diff --git a/deps/libvita2d/source/vita2d_font.c b/deps/libvita2d/source/vita2d_font.c old mode 100644 new mode 100755 index e90322200f..40e266ebed --- a/deps/libvita2d/source/vita2d_font.c +++ b/deps/libvita2d/source/vita2d_font.c @@ -11,16 +11,16 @@ #include "utils.h" #include "shared.h" -#define ATLAS_DEFAULT_W 256 -#define ATLAS_DEFAULT_H 256 +#define ATLAS_DEFAULT_W 512 +#define ATLAS_DEFAULT_H 512 typedef enum { - VITA2D_LOAD_FROM_FILE, - VITA2D_LOAD_FROM_MEM -} vita2d_font_load_from; + VITA2D_LOAD_FONT_FROM_FILE, + VITA2D_LOAD_FONT_FROM_MEM +} vita2d_load_font_from; typedef struct vita2d_font { - vita2d_font_load_from load_from; + vita2d_load_font_from load_from; union { char *filename; struct { @@ -32,22 +32,23 @@ typedef struct vita2d_font { FTC_Manager ftcmanager; FTC_CMapCache cmapcache; FTC_ImageCache imagecache; - texture_atlas *tex_atlas; + texture_atlas *atlas; } 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; 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( font->ftlibrary, font->filename, 0, 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( font->ftlibrary, font->font_buffer, @@ -82,21 +83,19 @@ vita2d_font *vita2d_load_font_file(const char *filename) &font->ftcmanager); if (error != FT_Err_Ok) { - free(font); FT_Done_FreeType(font->ftlibrary); + free(font); return NULL; } - size_t len = strlen(filename); - font->filename = malloc(len + 1); - strcpy(font->filename, filename); + font->filename = strdup(filename); FTC_CMapCache_New(font->ftcmanager, &font->cmapcache); 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); return font; @@ -126,8 +125,8 @@ vita2d_font *vita2d_load_font_mem(const void *buffer, unsigned int size) &font->ftcmanager); if (error != FT_Err_Ok) { - free(font); FT_Done_FreeType(font->ftlibrary); + free(font); 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_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); return font; @@ -151,60 +150,91 @@ void vita2d_free_font(vita2d_font *font) FTC_FaceID face_id = (FTC_FaceID)font; FTC_Manager_RemoveFaceID(font->ftcmanager, face_id); 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); } - texture_atlas_free(font->tex_atlas); + texture_atlas_free(font->atlas); 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; - - unsigned char *buffer = malloc(bitmap->width * bitmap->rows); unsigned int w = bitmap->width; unsigned int h = bitmap->rows; + unsigned char buffer[w * h]; - int j, k; - for (j = 0; j < h; j++) { - for (k = 0; k < w; k++) { + bp2d_size size = { + bitmap->width, + 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) { - buffer[j*w + k] = - (bitmap->buffer[j*bitmap->pitch + k/8] & (1 << (7 - k%8))) + buffer[i*w + j] = + (bitmap->buffer[i*bitmap->pitch + j/8] & (1 << (7 - j%8))) ? 0xFF : 0; - } else { - buffer[j*w + k] = bitmap->buffer[j*bitmap->pitch + k]; + } else if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) { + buffer[i*w + j] = bitmap->buffer[i*bitmap->pitch + j]; } } } - int ret = texture_atlas_insert_draw(atlas, glyph_index, buffer, - bitmap->width, bitmap->rows, - bitmap_glyph->left, bitmap_glyph->top, - bitmap_glyph->root.advance.x, bitmap_glyph->root.advance.y, - glyph_size); + texture_data = vita2d_texture_get_datap(atlas->texture); + tex_width = vita2d_texture_get_width(atlas->texture); - 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; - 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; + FT_UInt glyph_index; + 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_y = y + size; + int pen_y = y; + bp2d_rectangle rect; + texture_atlas_entry_data data; FTC_ScalerRec scaler; 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.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 (*text == '\n') { - if ((pen_x - x) > max) - max = pen_x-x; - pen_x = x; + if (character == '\n') { + if (pen_x > max_x) + max_x = pen_x; + pen_x = start_x; pen_y += size; - text++; 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) { 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; } - if (!texture_atlas_exists(font->tex_atlas, glyph_index)) { - FTC_ImageCache_LookupScaler(font->imagecache, &scaler, flags, glyph_index, &glyph, NULL); + if (!texture_atlas_get(font->atlas, glyph_index, &rect, &data)) { + 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; } + + if (!texture_atlas_get(font->atlas, glyph_index, &rect, &data)) + continue; } - bp2d_rectangle rect; - int bitmap_left, bitmap_top; - int advance_x, advance_y; - int glyph_size; + const float draw_scale = size / (float)data.glyph_size; - if (!texture_atlas_get(font->tex_atlas, glyph_index, - &rect, &bitmap_left, &bitmap_top, - &advance_x, &advance_y, &glyph_size)) - continue; + if (draw) { + vita2d_draw_texture_tint_part_scale(tex, + pen_x + data.bitmap_left * draw_scale, + 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; - - 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++; + pen_x += (data.advance_x >> 16) * draw_scale; } - 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]; va_list argptr; + va_start(argptr, text); vsnprintf(buf, sizeof(buf), text, 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; - FT_Face face; - FTC_Manager_LookupFace(font->ftcmanager, face_id, &face); + int w; + w = generic_font_draw_text(font, 0, height, 0, 0, 0, size, text); - 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) - *width = max; - if (height) - *height = size + pen_y; + *width = w; } int vita2d_font_text_width(vita2d_font *font, unsigned int size, const char *text) diff --git a/deps/libvita2d/source/vita2d_image_bmp.c b/deps/libvita2d/source/vita2d_image_bmp.c old mode 100644 new mode 100755 diff --git a/deps/libvita2d/source/vita2d_image_jpeg.c b/deps/libvita2d/source/vita2d_image_jpeg.c old mode 100644 new mode 100755 diff --git a/deps/libvita2d/source/vita2d_image_png.c b/deps/libvita2d/source/vita2d_image_png.c old mode 100644 new mode 100755 diff --git a/deps/libvita2d/source/vita2d_pgf.c b/deps/libvita2d/source/vita2d_pgf.c old mode 100644 new mode 100755 index 8b7c256f56..79a98a34fe --- a/deps/libvita2d/source/vita2d_pgf.c +++ b/deps/libvita2d/source/vita2d_pgf.c @@ -12,13 +12,14 @@ #include "utils.h" #include "shared.h" -#define ATLAS_DEFAULT_W 256 -#define ATLAS_DEFAULT_H 256 +#define ATLAS_DEFAULT_W 512 +#define ATLAS_DEFAULT_H 512 typedef struct vita2d_pgf { SceFontLibHandle lib_handle; SceFontHandle font_handle; - texture_atlas *tex_atlas; + texture_atlas *atlas; + float vsize; } vita2d_pgf; 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() { unsigned int error; + SceFontInfo fontinfo; vita2d_pgf *font = malloc(sizeof(*font)); if (!font) @@ -59,14 +61,18 @@ vita2d_pgf *vita2d_load_default_pgf() 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) { sceFontDoneLib(font->lib_handle); free(font); 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); return font; @@ -77,7 +83,7 @@ void vita2d_free_pgf(vita2d_pgf *font) if (font) { sceFontClose(font->font_handle); sceFontDoneLib(font->lib_handle); - texture_atlas_free(font->tex_atlas); + texture_atlas_free(font->atlas); 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) { SceFontCharInfo char_info; + bp2d_position position; + void *texture_data; + vita2d_texture *tex = font->atlas->texture; + if (sceFontGetCharInfo(font->font_handle, character, &char_info) < 0) return 0; - int pos_x; - int pos_y; - if (!texture_atlas_insert(font->tex_atlas, character, - char_info.bitmapWidth, char_info.bitmapHeight, - char_info.bitmapLeft, char_info.bitmapTop, + bp2d_size size = { + char_info.bitmapWidth, + char_info.bitmapHeight + }; + + texture_atlas_entry_data data = { + char_info.bitmapLeft, + char_info.bitmapTop, char_info.sfp26AdvanceH, char_info.sfp26AdvanceV, - 0, &pos_x, &pos_y)) + 0 + }; + + if (!texture_atlas_insert(font->atlas, character, &size, &data, + &position)) return 0; - vita2d_texture *tex = font->tex_atlas->tex; + texture_data = vita2d_texture_get_datap(tex); SceFontGlyphImage glyph_image; glyph_image.pixelFormat = SCE_FONT_PIXELFORMAT_8; - glyph_image.xPos64 = pos_x << 6; - glyph_image.yPos64 = pos_y << 6; + glyph_image.xPos64 = position.x << 6; + glyph_image.yPos64 = position.y << 6; glyph_image.bufWidth = vita2d_texture_get_width(tex); glyph_image.bufHeight = vita2d_texture_get_height(tex); glyph_image.bytesPerLine = vita2d_texture_get_stride(tex); 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; } -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_y = y; 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)) { continue; } + + if (!texture_atlas_get(font->atlas, character, + &rect, &data)) + continue; } - bp2d_rectangle rect; - int bitmap_left, bitmap_top; - int advance_x, advance_y; + if (draw) { + vita2d_draw_texture_tint_part_scale(tex, + 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, - &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; + pen_x += (data.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]; 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); } -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 max_h = 0; - - 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; - } + int w; + w = generic_pgf_draw_text(font, 0, height, 0, 0, 0, scale, text); if (width) - *width = pen_x; - if (height) - *height = max_h; + *width = w; } int vita2d_pgf_text_width(vita2d_pgf *font, float scale, const char *text) diff --git a/deps/libvita2d/source/vita2d_texture.c b/deps/libvita2d/source/vita2d_texture.c index 374368042b..86b30fbb26 100644 --- a/deps/libvita2d/source/vita2d_texture.c +++ b/deps/libvita2d/source/vita2d_texture.c @@ -178,6 +178,7 @@ static inline void set_texture_wvp_uniform() { void *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); } @@ -648,3 +649,44 @@ void vita2d_draw_texture_tint_scale_rotate(const vita2d_texture *texture, float rad, vita2d_texture_get_width(texture)/2.0f, 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); +} diff --git a/gfx/common/vita2d_common.h b/gfx/common/vita2d_common.h new file mode 100644 index 0000000000..836e21e619 --- /dev/null +++ b/gfx/common/vita2d_common.h @@ -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 . + */ + +#ifndef VITA2D_COMMON_H__ +#define VITA2D_COMMON_H__ + +#include + +#include +#include + +#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 diff --git a/gfx/drivers/vita2d_gfx.c b/gfx/drivers/vita2d_gfx.c index 9da5992f32..75bec30dc9 100644 --- a/gfx/drivers/vita2d_gfx.c +++ b/gfx/drivers/vita2d_gfx.c @@ -20,70 +20,25 @@ #include #include "../../defines/psp_defines.h" +#include "../common/vita2d_common.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; -}; +#ifdef HAVE_MENU +#include "../../menu/menu_driver.h" #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; - 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_set_viewport(void *data, unsigned viewport_width, + unsigned viewport_height, bool force_full, bool allow_rotate); + static void *vita2d_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { vita_video_t *vita = (vita_video_t *)calloc(1, sizeof(vita_video_t)); settings_t *settings = config_get_ptr(); + unsigned temp_width = PSP_FB_WIDTH; + unsigned temp_height = PSP_FB_HEIGHT; if (!vita) return NULL; @@ -124,6 +79,10 @@ static void *vita2d_gfx_init(const video_info_t *video, vita->tex_filter = video->smooth ? 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) { void *pspinput = input_psp.init(); @@ -260,34 +219,42 @@ static bool vita2d_gfx_frame(void *data, const void *frame, vita2d_render_overlay(vita); #endif - if (vita->menu.active && vita->menu.texture) + if (vita->menu.active) { - if (vita->fullscreen) - vita2d_draw_texture_scale(vita->menu.texture, - 0, 0, - PSP_FB_WIDTH / (float)vita->menu.width, - PSP_FB_HEIGHT / (float)vita->menu.height); - else - { - if (vita->menu.width > vita->menu.height) - { - float scale = PSP_FB_HEIGHT / (float)vita->menu.height; - float w = vita->menu.width * scale; - vita2d_draw_texture_scale(vita->menu.texture, - PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f, - scale, scale); - } - else - { - float scale = PSP_FB_WIDTH / (float)vita->menu.width; - float h = vita->menu.height * scale; - vita2d_draw_texture_scale(vita->menu.texture, - 0.0f, PSP_FB_HEIGHT / 2.0f - h/2.0f, - scale, scale); - } - } + + if(vita->menu.texture){ + if (vita->fullscreen) + vita2d_draw_texture_scale(vita->menu.texture, + 0, 0, + PSP_FB_WIDTH / (float)vita->menu.width, + PSP_FB_HEIGHT / (float)vita->menu.height); + else + { + if (vita->menu.width > vita->menu.height) + { + float scale = PSP_FB_HEIGHT / (float)vita->menu.height; + float w = vita->menu.width * scale; + vita2d_draw_texture_scale(vita->menu.texture, + PSP_FB_WIDTH / 2.0f - w/2.0f, 0.0f, + scale, scale); + } + else + { + float scale = PSP_FB_WIDTH / (float)vita->menu.width; + float h = vita->menu.height * 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)) font_driver_render_msg(NULL, msg, NULL); @@ -366,6 +333,25 @@ static bool vita2d_gfx_set_shader(void *data, 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) { 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, unsigned rotation) { @@ -603,9 +693,57 @@ static void vita_set_texture_enable(void *data, bool state, bool full_screen) 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 = { - NULL, - NULL, + vita_load_texture, + vita_unload_texture, NULL, vita_set_filtering, NULL, /* get_video_output_size */ @@ -618,10 +756,18 @@ static const video_poke_interface_t vita_poke_interface = { #ifdef HAVE_MENU vita_set_texture_frame, vita_set_texture_enable, -#endif - NULL, - NULL, - NULL + #else + 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, @@ -779,7 +925,7 @@ video_driver_t video_vita2d = { vita2d_gfx_set_shader, vita2d_gfx_free, "vita2d", - NULL, /* set_viewport */ + vita2d_gfx_set_viewport, vita2d_gfx_set_rotation, vita2d_gfx_viewport_info, vita2d_gfx_read_viewport, diff --git a/gfx/drivers_font/vita2d_font.c b/gfx/drivers_font/vita2d_font.c index bee2aa1008..b6bd1a4515 100644 --- a/gfx/drivers_font/vita2d_font.c +++ b/gfx/drivers_font/vita2d_font.c @@ -10701,29 +10701,51 @@ static void vita2d_font_free_font(void *data) 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, const void *userdata) { float x, y, scale; unsigned color; + unsigned width, height, text_height; settings_t *settings = config_get_ptr(); vita_font_t *vita = (vita_font_t *)data; const struct font_params *params = (const struct font_params*)userdata; (void)data; + + video_driver_get_size(&width, &height); if (params) { - x = params->x; - y = params->y; - scale = params->scale; + scale = params->scale; + text_height = vita2d_font_text_height(vita->font, vita->size*scale, msg); + x = params->x*width; + y = (1-params->y)*height;//-(text_height/4); 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 { - x = settings->video.msg_pos_x; - y = 0.90f; - scale = 0.8f; + scale = 0.8f; + text_height = vita2d_font_text_height(vita->font, vita->size*scale, msg); + x = settings->video.msg_pos_x; + y = text_height; color = YELLOW; } @@ -10738,5 +10760,5 @@ font_renderer_t vita2d_vita_font = { NULL, /* get_glyph */ NULL, /* bind_block */ NULL, /* flush */ - NULL, /* get_message_width */ + vita2d_font_get_message_width, }; diff --git a/griffin/griffin.c b/griffin/griffin.c index 0741cfe4c4..29325bf86b 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -918,6 +918,10 @@ MENU #include "../menu/drivers_display/menu_display_vulkan.c" #endif +#ifdef HAVE_VITA2D +#include "../menu/drivers_display/menu_display_vita2d.c" +#endif + #endif @@ -925,8 +929,7 @@ MENU #include "../menu/drivers/rgui.c" #endif -#ifdef HAVE_OPENGL - +#if defined(HAVE_OPENGL) || defined(HAVE_VITA2D) #ifdef HAVE_XMB #include "../menu/drivers/xmb.c" #endif diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 801354e771..32cddf1213 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -515,8 +515,13 @@ static void xmb_draw_icon( coords.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.height = icon_size; +#endif draw.coords = &coords; draw.matrix_data = mymat; draw.texture = texture; @@ -533,14 +538,24 @@ static void xmb_draw_icon( coords.color = shadow; draw.x = x + 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); } coords.color = (const float*)color; draw.x = x; 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); } @@ -1999,6 +2014,8 @@ static void xmb_draw_bg( menu_display_ctx_draw_t draw; settings_t *settings = config_get_ptr(); + RARCH_LOG("DRAW BG %d %d \n",width,height); + bool running = menu_display_libretro_running(); draw.x = 0; diff --git a/menu/drivers_display/menu_display_vita2d.c b/menu/drivers_display/menu_display_vita2d.c new file mode 100644 index 0000000000..91a89fcc4b --- /dev/null +++ b/menu/drivers_display/menu_display_vita2d.c @@ -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 . + */ + +#include + +#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 + +#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", +}; diff --git a/menu/menu_display.c b/menu/menu_display.c index d72444a7b7..222d882c5a 100644 --- a/menu/menu_display.c +++ b/menu/menu_display.c @@ -51,6 +51,9 @@ static menu_display_ctx_driver_t *menu_display_ctx_drivers[] = { #endif #ifdef HAVE_VULKAN &menu_display_ctx_vulkan, +#endif +#ifdef HAVE_VITA2D + &menu_display_ctx_vita2d, #endif &menu_display_ctx_null, NULL, @@ -89,6 +92,10 @@ static bool menu_display_check_compatibility( if (string_is_equal(video_driver, "d3d")) return true; break; + case MENU_VIDEO_DRIVER_VITA2D: + if (string_is_equal(video_driver, "vita2d")) + return true; + break; } 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) { +#if !defined(VITA) math_matrix_4x4 matrix_rotated, matrix_scaled; 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, draw->scale_x, draw->scale_y, draw->scale_z); matrix_4x4_multiply(draw->matrix, &matrix_scaled, draw->matrix); +#endif } bool menu_display_get_tex_coords(menu_display_ctx_coord_draw_t *draw) diff --git a/menu/menu_display.h b/menu/menu_display.h index df0162965e..145d129519 100644 --- a/menu/menu_display.h +++ b/menu/menu_display.h @@ -85,7 +85,8 @@ enum menu_display_driver_type MENU_VIDEO_DRIVER_GENERIC = 0, MENU_VIDEO_DRIVER_OPENGL, MENU_VIDEO_DRIVER_VULKAN, - MENU_VIDEO_DRIVER_DIRECT3D + MENU_VIDEO_DRIVER_DIRECT3D, + MENU_VIDEO_DRIVER_VITA2D }; 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_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_null; RETRO_END_DECLS