From 518b53e21cbff210338237a48de9d5092949be47 Mon Sep 17 00:00:00 2001 From: Toad King Date: Tue, 18 Feb 2014 18:20:23 -0500 Subject: [PATCH 1/8] convert images on texture_image_load for gekko --- gfx/image.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/gfx/image.c b/gfx/image.c index 99e5b682bb..904aae8034 100644 --- a/gfx/image.c +++ b/gfx/image.c @@ -224,13 +224,105 @@ bool texture_image_load_argb_shift(const char *path, struct texture_image *out_i #endif +#ifdef GEKKO + +#define GX_BLIT_LINE_32(off) \ +{ \ + const uint16_t *tmp_src = src; \ + uint16_t *tmp_dst = dst; \ + for (unsigned x = 0; x < width2 >> 2; x += 8, tmp_src += 32, tmp_dst += 128) \ + { \ + tmp_dst[ 0 + off] = tmp_src[0]; \ + tmp_dst[ 16 + off] = tmp_src[1]; \ + tmp_dst[ 1 + off] = tmp_src[2]; \ + tmp_dst[ 17 + off] = tmp_src[3]; \ + tmp_dst[ 2 + off] = tmp_src[4]; \ + tmp_dst[ 18 + off] = tmp_src[5]; \ + tmp_dst[ 3 + off] = tmp_src[6]; \ + tmp_dst[ 19 + off] = tmp_src[7]; \ + tmp_dst[ 32 + off] = tmp_src[8]; \ + tmp_dst[ 48 + off] = tmp_src[9]; \ + tmp_dst[ 33 + off] = tmp_src[10]; \ + tmp_dst[ 49 + off] = tmp_src[11]; \ + tmp_dst[ 34 + off] = tmp_src[12]; \ + tmp_dst[ 50 + off] = tmp_src[13]; \ + tmp_dst[ 35 + off] = tmp_src[14]; \ + tmp_dst[ 51 + off] = tmp_src[15]; \ + tmp_dst[ 64 + off] = tmp_src[16]; \ + tmp_dst[ 80 + off] = tmp_src[17]; \ + tmp_dst[ 65 + off] = tmp_src[18]; \ + tmp_dst[ 81 + off] = tmp_src[19]; \ + tmp_dst[ 66 + off] = tmp_src[20]; \ + tmp_dst[ 82 + off] = tmp_src[21]; \ + tmp_dst[ 67 + off] = tmp_src[22]; \ + tmp_dst[ 83 + off] = tmp_src[23]; \ + tmp_dst[ 96 + off] = tmp_src[24]; \ + tmp_dst[112 + off] = tmp_src[25]; \ + tmp_dst[ 97 + off] = tmp_src[26]; \ + tmp_dst[113 + off] = tmp_src[27]; \ + tmp_dst[ 98 + off] = tmp_src[28]; \ + tmp_dst[114 + off] = tmp_src[29]; \ + tmp_dst[ 99 + off] = tmp_src[30]; \ + tmp_dst[115 + off] = tmp_src[31]; \ + } \ + src += tmp_pitch; \ +} + +static bool gx_convert_texture32(struct texture_image *image) +{ + // memory allocation in libogc is extremely primitive so try to avoid gaps in memory when converting + // by copying over to temp buffer first then converting over into main buffer again + void *tmp = malloc(width * height * sizeof(uint32_t)); + + if (!tmp) + { + RARCH_ERR("Failed to create temp buffer for conversion.\n"); + return false; + } + + memcpy(tmp, image->pixels, image->width * image->height * sizeof(uint32_t)); + unsigned tmp_pitch = (image->width * sizeof(uint32_t)) >> 1; + image->width &= ~3; + image->height &= ~3; + unsigned width2 = image->width << 1; + + const uint16_t *src = (uint16_t *) tmp; + uint16_t *dst = (uint16_t *) image->pixels; + for (unsigned i = 0; i < image->height; i += 4, dst += 4 * width2) + { + GX_BLIT_LINE_32(0) + GX_BLIT_LINE_32(4) + GX_BLIT_LINE_32(8) + GX_BLIT_LINE_32(12) + } + + free(tmp); + return true; +} + +#endif + bool texture_image_load(const char *path, struct texture_image *out_img) { + bool ret; // This interface "leak" is very ugly. FIXME: Fix this properly ... if (driver.gfx_use_rgba) - return texture_image_load_argb_shift(path, out_img, 24, 0, 8, 16); + ret = texture_image_load_argb_shift(path, out_img, 24, 0, 8, 16); else - return texture_image_load_argb_shift(path, out_img, 24, 16, 8, 0); + ret = texture_image_load_argb_shift(path, out_img, 24, 16, 8, 0); + +#ifdef GEKKO + if (ret) + { + if (!gx_convert_texture32(out_img)) + { + texture_image_free(out_img); + ret = false; + } + } +#endif + + return ret; } void texture_image_free(struct texture_image *img) From e09b7fb60c6152958185086674654ec9d38f25d2 Mon Sep 17 00:00:00 2001 From: Toad King Date: Wed, 19 Feb 2014 17:52:47 -0500 Subject: [PATCH 2/8] build fix --- gfx/image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/image.c b/gfx/image.c index 904aae8034..a030e96296 100644 --- a/gfx/image.c +++ b/gfx/image.c @@ -272,7 +272,7 @@ static bool gx_convert_texture32(struct texture_image *image) { // memory allocation in libogc is extremely primitive so try to avoid gaps in memory when converting // by copying over to temp buffer first then converting over into main buffer again - void *tmp = malloc(width * height * sizeof(uint32_t)); + void *tmp = malloc(image->width * image->height * sizeof(uint32_t)); if (!tmp) { From fe4ec8fd7cbf560b06034db92816328a4807debb Mon Sep 17 00:00:00 2001 From: Toad King Date: Wed, 19 Feb 2014 17:53:23 -0500 Subject: [PATCH 3/8] [GX] overlay implementation *COMPLETELY UNTESTED, PROBABLY DOESN'T WORK YET* --- gx/gx_video.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ gx/gx_video.h | 14 ++++++ 2 files changed, 144 insertions(+) diff --git a/gx/gx_video.c b/gx/gx_video.c index ca35dca66e..3f51d7db95 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -1073,6 +1073,133 @@ static void gx_get_poke_interface(void *data, const video_poke_interface_t **ifa *iface = &gx_poke_interface; } +#ifdef HAVE_OVERLAY +static void gx_free_overlay(gx_t *gx); +static bool gx_overlay_load(void *data, const struct texture_image *images, unsigned num_images) +{ + unsigned i; + gx_video_t *gx = (gx_video_t*)data; + + gx_free_overlay(gx); + gx->overlay = (struct gx_overlay_data*)calloc(num_images, sizeof(*gx->overlay)); + if (!gx->overlay) + return false; + + gx->overlays = num_images; + + for (i = 0; i < num_images; i++) + { + struct gx_overlay_data *data = &gx->overlay[i]; + GX_InitTexObj(&data->tex, images[i].pixels, images[i].width, images[i].height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + GX_InitTexObjFilterMode(&g_tex.obj, GX_LINEAR, GX_LINEAR); + DCFlushRange(images[i].pixels, images[i].width * images[i].height * sizeof(uint32_t)); + gx_overlay_tex_geom(gx, i, 0, 0, 1, 1); // Default. Stretch to whole screen. + gx_overlay_vertex_geom(gx, i, 0, 0, 1, 1); + gx->overlay[i].alpha_mod = 1.0f; + } + + GX_InvalidateTexAll(); + return true; +} + +static void gx_overlay_tex_geom(void *data, + unsigned image, + GLfloat x, GLfloat y, + GLfloat w, GLfloat h) +{ + gx_video_t *gx = (gx_video_t*)data; + struct gx_overlay_data *o = &gx->overlay[image]; + + o->tex_coord[0] = x; o->tex_coord[1] = y; + o->tex_coord[2] = x + w; o->tex_coord[3] = y; + o->tex_coord[4] = x; o->tex_coord[5] = y + h; + o->tex_coord[6] = x + w; o->tex_coord[7] = y + h; +} + +static void gx_overlay_vertex_geom(void *data, + unsigned image, + float x, float y, + float w, float h) +{ + gx_video_t *gx = (gx_video_t*)data; + struct gx_overlay_data *o = &gx->overlay[image]; + + o->vertex_coord[0] = x; o->vertex_coord[1] = y; + o->vertex_coord[2] = x + w; o->vertex_coord[3] = y; + o->vertex_coord[4] = x; o->vertex_coord[5] = y + h; + o->vertex_coord[6] = x + w; o->vertex_coord[7] = y + h; +} + +static void gx_overlay_enable(void *data, bool state) +{ + gx_video_t *gx = (gx_video_t*)data; + gx->overlay_enable = state; +} + +static void gx_overlay_full_screen(void *data, bool enable) +{ + gx_video_t *gx = (gx_video_t*)data; + gx->overlay_full_screen = enable; +} + +static void gx_overlay_set_alpha(void *data, unsigned image, float mod) +{ + gx_video_t *gx = (gx_video_t*)data; + gx->overlay[image].alpha_mod = mod; +} + +static void gx_render_overlay(void *data) +{ + unsigned i, j; + gx_t *gx = (gx_t*)data; + + /*if (gx->overlay_full_screen) + glViewport(0, 0, gx->win_width, gx->win_height);*/ + + GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); + GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + for (i = 0; i < gx->overlays; i++) + { + GX_LoadTexObj(&gx->overlay[i].tex, GX_TEXMAP0); + + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position3f32(gx->overlay[i].vertex_coord[0], gx->overlay[i].vertex_coord[1], 0); + GX_TexCoord2f32(gx->overlay[i].tex_coord[0], gx->overlay[i].tex_coord[1]); + + GX_Position3f32(gx->overlay[i].vertex_coord[2], gx->overlay[i].vertex_coord[3], 0); + GX_TexCoord2f32(gx->overlay[i].tex_coord[2], gx->overlay[i].tex_coord[3]); + + GX_Position3f32(gx->overlay[i].vertex_coord[4], gx->overlay[i].vertex_coord[5], 0); + GX_TexCoord2f32(gx->overlay[i].tex_coord[4], gx->overlay[i].tex_coord[5]); + + GX_Position3f32(gx->overlay[i].vertex_coord[6], gx->overlay[i].vertex_coord[7], 0); + GX_TexCoord2f32(gx->overlay[i].tex_coord[6], gx->overlay[i].tex_coord[7]); + GX_End(); + } + + GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); + GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX8); + + /*if (gx->overlay_full_screen) + glViewport(gx->vp.x, gx->vp.y, gx->vp.width, gx->vp.height);*/ +} + +static const video_overlay_interface_t gx_overlay_interface = { + gx_overlay_enable, + gx_overlay_load, + gx_overlay_tex_geom, + gx_overlay_vertex_geom, + gx_overlay_full_screen, + gx_overlay_set_alpha, +}; + +static void gx_get_overlay_interface(void *data, const video_overlay_interface_t **iface) +{ + (void)data; + *iface = &gx_overlay_interface; +} +#endif + const video_driver_t video_gx = { .init = gx_init, .frame = gx_frame, @@ -1084,5 +1211,8 @@ const video_driver_t video_gx = { .set_rotation = gx_set_rotation, .viewport_info = gx_viewport_info, .restart = gx_restart, +#ifdef HAVE_OVERLAY + .overlay_interface = gx_get_overlay_interface, +#endif .poke_interface = gx_get_poke_interface, }; diff --git a/gx/gx_video.h b/gx/gx_video.h index c70a12485a..604c81b917 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -18,6 +18,14 @@ #ifndef _GX_VIDEO_H__ #define _GX_VIDEO_H__ +struct gx_overlay_data +{ + unsigned tex; + float tex_coord[8]; + float vertex_coord[8]; + float alpha_mod; +}; + typedef struct gx_video { bool should_resize; @@ -28,6 +36,12 @@ typedef struct gx_video bool rgui_texture_enable; rarch_viewport_t vp; unsigned scale; +#ifdef HAVE_OVERLAY + struct gx_overlay_data *overlay; + unsigned overlays; + bool overlay_enable; + bool overlay_full_screen; +#endif } gx_video_t; void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines); From be9c017c366525e3c48ccf5952b23453b591d3d4 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 20 Feb 2014 16:23:29 -0500 Subject: [PATCH 4/8] [GX] builds with overlay support, nothing displayed yet --- Makefile.wii | 2 +- gx/gx_video.c | 46 ++++++++++++++++++++++++++++++++++------------ gx/gx_video.h | 2 +- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Makefile.wii b/Makefile.wii index 455935952e..7843db95f3 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -63,7 +63,7 @@ CFLAGS += -Iconsole/logger endif -CFLAGS += -std=gnu99 -DSINC_LOWER_QUALITY -DHAVE_RGUI -DHAVE_MENU -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DGEKKO -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DHAVE_THREADS -DHAVE_RSOUND -Wno-char-subscripts -DRARCH_INTERNAL +CFLAGS += -std=gnu99 -DSINC_LOWER_QUALITY -DHAVE_RGUI -DHAVE_MENU -DRARCH_CONSOLE -DHAVE_LIBRETRO_MANAGEMENT -DHAVE_RARCH_EXEC -DGEKKO -DHAVE_ZLIB -DWANT_MINIZ -DHAVE_GRIFFIN=1 -DHAVE_SCREENSHOTS -DHAVE_THREADS -DHAVE_RSOUND -Wno-char-subscripts -DRARCH_INTERNAL -DHAVE_OVERLAY -DWANT_RPNG ifeq ($(DEBUG), 1) CFLAGS += -O0 -g -DDEBUG diff --git a/gx/gx_video.c b/gx/gx_video.c index 3f51d7db95..23cfbf79e1 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -94,6 +94,21 @@ static void retrace_callback(u32 retrace_count) extern rgui_handle_t *rgui; + +#ifdef HAVE_OVERLAY +static void gx_render_overlay(void *data); +static void gx_free_overlay(gx_video_t *gx) +{ +#ifdef GX_OPTS + struct __gx_regdef *__gx = (struct __gx_regdef*)__gxregs; +#endif + free(gx->overlay); + gx->overlay = NULL; + gx->overlays = 0; + GX_InvalidateTexAll(); +} +#endif + void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines) { unsigned modetype, level, viHeightMultiplier, viWidth, tvmode, @@ -956,6 +971,11 @@ static bool gx_frame(void *data, const void *frame, GX_DrawDone(); } +#ifdef HAVE_OVERLAY + if (gx->overlay_enable) + gx_render_overlay(gx); +#endif + char fps_txt[128], fps_text_buf[128]; bool fps_draw = g_settings.fps_show; gfx_get_fps(fps_txt, sizeof(fps_txt), fps_draw ? fps_text_buf : NULL, sizeof(fps_text_buf)); @@ -1017,6 +1037,10 @@ static bool gx_focus(void *data) static void gx_free(void *data) { (void)data; +#ifdef HAVE_OVERLAY + gx_video_t *gx = (gx_video_t*)driver.video_data; + gx_free_overlay(gx); +#endif } static void gx_set_rotation(void *data, unsigned orientation) @@ -1074,11 +1098,15 @@ static void gx_get_poke_interface(void *data, const video_poke_interface_t **ifa } #ifdef HAVE_OVERLAY -static void gx_free_overlay(gx_t *gx); +static void gx_overlay_tex_geom(void *data, unsigned image, float x, float y, float w, float h); +static void gx_overlay_vertex_geom(void *data, unsigned image, float x, float y, float w, float h); static bool gx_overlay_load(void *data, const struct texture_image *images, unsigned num_images) { unsigned i; gx_video_t *gx = (gx_video_t*)data; +#ifdef GX_OPTS + struct __gx_regdef *__gx = (struct __gx_regdef*)__gxregs; +#endif gx_free_overlay(gx); gx->overlay = (struct gx_overlay_data*)calloc(num_images, sizeof(*gx->overlay)); @@ -1102,10 +1130,7 @@ static bool gx_overlay_load(void *data, const struct texture_image *images, unsi return true; } -static void gx_overlay_tex_geom(void *data, - unsigned image, - GLfloat x, GLfloat y, - GLfloat w, GLfloat h) +static void gx_overlay_tex_geom(void *data, unsigned image, float x, float y, float w, float h) { gx_video_t *gx = (gx_video_t*)data; struct gx_overlay_data *o = &gx->overlay[image]; @@ -1116,10 +1141,7 @@ static void gx_overlay_tex_geom(void *data, o->tex_coord[6] = x + w; o->tex_coord[7] = y + h; } -static void gx_overlay_vertex_geom(void *data, - unsigned image, - float x, float y, - float w, float h) +static void gx_overlay_vertex_geom(void *data, unsigned image, float x, float y, float w, float h) { gx_video_t *gx = (gx_video_t*)data; struct gx_overlay_data *o = &gx->overlay[image]; @@ -1150,15 +1172,15 @@ static void gx_overlay_set_alpha(void *data, unsigned image, float mod) static void gx_render_overlay(void *data) { - unsigned i, j; - gx_t *gx = (gx_t*)data; + gx_video_t *gx = (gx_video_t*)data; /*if (gx->overlay_full_screen) glViewport(0, 0, gx->win_width, gx->win_height);*/ + GX_SetCurrentMtx(GX_PNMTX1); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); - for (i = 0; i < gx->overlays; i++) + for (unsigned i = 0; i < gx->overlays; i++) { GX_LoadTexObj(&gx->overlay[i].tex, GX_TEXMAP0); diff --git a/gx/gx_video.h b/gx/gx_video.h index 604c81b917..2a7cfeb2a4 100644 --- a/gx/gx_video.h +++ b/gx/gx_video.h @@ -20,7 +20,7 @@ struct gx_overlay_data { - unsigned tex; + GXTexObj tex; float tex_coord[8]; float vertex_coord[8]; float alpha_mod; From 8762d74fb6bf26e759a9d88e82f49c184ad13f8f Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 20 Feb 2014 16:26:50 -0500 Subject: [PATCH 5/8] [GX] buildfix --- gx/gx_video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gx/gx_video.c b/gx/gx_video.c index 23cfbf79e1..8b41dc2220 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -1173,6 +1173,9 @@ static void gx_overlay_set_alpha(void *data, unsigned image, float mod) static void gx_render_overlay(void *data) { gx_video_t *gx = (gx_video_t*)data; +#ifdef GX_OPTS + struct __gx_regdef *__gx = (struct __gx_regdef*)__gxregs; +#endif /*if (gx->overlay_full_screen) glViewport(0, 0, gx->win_width, gx->win_height);*/ From 02fd6dffbd6aadfed351f9ea658ce4371ad6e583 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 20 Feb 2014 17:58:06 -0500 Subject: [PATCH 6/8] [GX] overlays appear, still some bugs left --- gfx/rpng/rpng.c | 9 +++++++++ gx/gx_video.c | 34 ++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/gfx/rpng/rpng.c b/gfx/rpng/rpng.c index a00dfa4953..2c1b7afe74 100644 --- a/gfx/rpng/rpng.c +++ b/gfx/rpng/rpng.c @@ -21,6 +21,10 @@ #include #include +#ifdef GEKKO +#include +#endif + #ifdef RARCH_INTERNAL #include "../../hash.h" #else @@ -709,7 +713,12 @@ bool rpng_load_image_argb(const char *path, uint32_t **data, unsigned *width, un *width = ihdr.width; *height = ihdr.height; +#ifdef GEKKO + // we often use these in textures, make sure they're 32-byte aligned + *data = (uint32_t*)memalign(32, ihdr.width * ihdr.height * sizeof(uint32_t)); +#else *data = (uint32_t*)malloc(ihdr.width * ihdr.height * sizeof(uint32_t)); +#endif if (!*data) GOTO_END_ERROR(); diff --git a/gx/gx_video.c b/gx/gx_video.c index 8b41dc2220..30f32141c2 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -73,16 +73,16 @@ unsigned gx_old_width, gx_old_height; float verts[16] ATTRIBUTE_ALIGN(32) = { -1, 1, -0.5, + 1, 1, -0.5, -1, -1, -0.5, 1, -1, -0.5, - 1, 1, -0.5, }; float vertex_ptr[8] ATTRIBUTE_ALIGN(32) = { 0, 0, + 1, 0, 0, 1, 1, 1, - 1, 0, }; static void retrace_callback(u32 retrace_count) @@ -398,8 +398,8 @@ static void init_vtx(void *data) GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); GX_InvVtxCache(); - GX_SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_INVSRCALPHA, 0); - + //GX_SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_INVSRCALPHA, 0); + GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); g_tex.data = memalign(32, 4 * 4 * 4); memset(g_tex.data, 0, 4 * 4 * 4); DCFlushRange(g_tex.data, 4 * 4 * 4); @@ -411,7 +411,7 @@ static void build_disp_list(void) { DCInvalidateRange(display_list, sizeof(display_list)); GX_BeginDispList(display_list, sizeof(display_list)); - GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); for (unsigned i = 0; i < 4; i++) { GX_Position1x8(i); @@ -1117,8 +1117,8 @@ static bool gx_overlay_load(void *data, const struct texture_image *images, unsi for (i = 0; i < num_images; i++) { - struct gx_overlay_data *data = &gx->overlay[i]; - GX_InitTexObj(&data->tex, images[i].pixels, images[i].width, images[i].height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); + struct gx_overlay_data *o = &gx->overlay[i]; + GX_InitTexObj(&o->tex, images[i].pixels, images[i].width, images[i].height, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); GX_InitTexObjFilterMode(&g_tex.obj, GX_LINEAR, GX_LINEAR); DCFlushRange(images[i].pixels, images[i].width * images[i].height * sizeof(uint32_t)); gx_overlay_tex_geom(gx, i, 0, 0, 1, 1); // Default. Stretch to whole screen. @@ -1146,6 +1146,16 @@ static void gx_overlay_vertex_geom(void *data, unsigned image, float x, float y, gx_video_t *gx = (gx_video_t*)data; struct gx_overlay_data *o = &gx->overlay[image]; + // Flipped, so we preserve top-down semantics. + y = 1.0f - y; + h = -h; + + // expand from 0 - 1 to -1 - 1 + x = (x * 2.0f) - 1.0f; + y = (y * 2.0f) - 1.0f; + w = (w * 2.0f); + h = (h * 2.0f); + o->vertex_coord[0] = x; o->vertex_coord[1] = y; o->vertex_coord[2] = x + w; o->vertex_coord[3] = y; o->vertex_coord[4] = x; o->vertex_coord[5] = y + h; @@ -1187,17 +1197,17 @@ static void gx_render_overlay(void *data) { GX_LoadTexObj(&gx->overlay[i].tex, GX_TEXMAP0); - GX_Begin(GX_QUADS, GX_VTXFMT0, 4); - GX_Position3f32(gx->overlay[i].vertex_coord[0], gx->overlay[i].vertex_coord[1], 0); + GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); + GX_Position3f32(gx->overlay[i].vertex_coord[0], gx->overlay[i].vertex_coord[1], -0.5); GX_TexCoord2f32(gx->overlay[i].tex_coord[0], gx->overlay[i].tex_coord[1]); - GX_Position3f32(gx->overlay[i].vertex_coord[2], gx->overlay[i].vertex_coord[3], 0); + GX_Position3f32(gx->overlay[i].vertex_coord[2], gx->overlay[i].vertex_coord[3], -0.5); GX_TexCoord2f32(gx->overlay[i].tex_coord[2], gx->overlay[i].tex_coord[3]); - GX_Position3f32(gx->overlay[i].vertex_coord[4], gx->overlay[i].vertex_coord[5], 0); + GX_Position3f32(gx->overlay[i].vertex_coord[4], gx->overlay[i].vertex_coord[5], -0.5); GX_TexCoord2f32(gx->overlay[i].tex_coord[4], gx->overlay[i].tex_coord[5]); - GX_Position3f32(gx->overlay[i].vertex_coord[6], gx->overlay[i].vertex_coord[7], 0); + GX_Position3f32(gx->overlay[i].vertex_coord[6], gx->overlay[i].vertex_coord[7], -0.5); GX_TexCoord2f32(gx->overlay[i].tex_coord[6], gx->overlay[i].tex_coord[7]); GX_End(); } From 96a339cb6f809ae5adc5cba8082e3a13fa6708fb Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 20 Feb 2014 18:58:40 -0500 Subject: [PATCH 7/8] [GX] fix lockup when using overlays --- gx/gx_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gx/gx_video.c b/gx/gx_video.c index 30f32141c2..af4bfe95fa 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -961,14 +961,12 @@ static bool gx_frame(void *data, const void *frame, GX_SetCurrentMtx(GX_PNMTX0); GX_LoadTexObj(&g_tex.obj, GX_TEXMAP0); GX_CallDispList(display_list, display_list_size); - GX_DrawDone(); if (gx->rgui_texture_enable) { GX_SetCurrentMtx(GX_PNMTX1); GX_LoadTexObj(&menu_tex.obj, GX_TEXMAP0); GX_CallDispList(display_list, display_list_size); - GX_DrawDone(); } #ifdef HAVE_OVERLAY @@ -976,6 +974,8 @@ static bool gx_frame(void *data, const void *frame, gx_render_overlay(gx); #endif + GX_DrawDone(); + char fps_txt[128], fps_text_buf[128]; bool fps_draw = g_settings.fps_show; gfx_get_fps(fps_txt, sizeof(fps_txt), fps_draw ? fps_text_buf : NULL, sizeof(fps_text_buf)); From 25f66ce28ae4dd8541318201b0ad88279beb2491 Mon Sep 17 00:00:00 2001 From: Toad King Date: Thu, 20 Feb 2014 19:26:50 -0500 Subject: [PATCH 8/8] [GX] add alpha to overlay --- gx/gx_video.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/gx/gx_video.c b/gx/gx_video.c index af4bfe95fa..eab63ea9e8 100644 --- a/gx/gx_video.c +++ b/gx/gx_video.c @@ -85,6 +85,13 @@ float vertex_ptr[8] ATTRIBUTE_ALIGN(32) = { 1, 1, }; +u8 color_ptr[16] ATTRIBUTE_ALIGN(32) = { + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, +}; + static void retrace_callback(u32 retrace_count) { (void)retrace_count; @@ -386,19 +393,22 @@ static void init_vtx(void *data) GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX8); + GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetArray(GX_VA_POS, verts, 3 * sizeof(float)); GX_SetArray(GX_VA_TEX0, vertex_ptr, 2 * sizeof(float)); + GX_SetArray(GX_VA_CLR0, color_ptr, 4 * sizeof(u8)); GX_SetNumTexGens(1); - GX_SetNumChans(0); - GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); - GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); + GX_SetNumChans(1); + GX_SetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHTNULL, GX_DF_NONE, GX_AF_NONE); + GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_InvVtxCache(); - //GX_SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_INVSRCALPHA, 0); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); g_tex.data = memalign(32, 4 * 4 * 4); memset(g_tex.data, 0, 4 * 4 * 4); @@ -415,6 +425,7 @@ static void build_disp_list(void) for (unsigned i = 0; i < 4; i++) { GX_Position1x8(i); + GX_Color1x8(i); GX_TexCoord1x8(i); } GX_End(); @@ -1187,36 +1198,37 @@ static void gx_render_overlay(void *data) struct __gx_regdef *__gx = (struct __gx_regdef*)__gxregs; #endif - /*if (gx->overlay_full_screen) - glViewport(0, 0, gx->win_width, gx->win_height);*/ - GX_SetCurrentMtx(GX_PNMTX1); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); + for (unsigned i = 0; i < gx->overlays; i++) { GX_LoadTexObj(&gx->overlay[i].tex, GX_TEXMAP0); GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); GX_Position3f32(gx->overlay[i].vertex_coord[0], gx->overlay[i].vertex_coord[1], -0.5); + GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f)); GX_TexCoord2f32(gx->overlay[i].tex_coord[0], gx->overlay[i].tex_coord[1]); GX_Position3f32(gx->overlay[i].vertex_coord[2], gx->overlay[i].vertex_coord[3], -0.5); + GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f)); GX_TexCoord2f32(gx->overlay[i].tex_coord[2], gx->overlay[i].tex_coord[3]); GX_Position3f32(gx->overlay[i].vertex_coord[4], gx->overlay[i].vertex_coord[5], -0.5); + GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f)); GX_TexCoord2f32(gx->overlay[i].tex_coord[4], gx->overlay[i].tex_coord[5]); GX_Position3f32(gx->overlay[i].vertex_coord[6], gx->overlay[i].vertex_coord[7], -0.5); + GX_Color4u8(255, 255, 255, (u8)(gx->overlay[i].alpha_mod * 255.0f)); GX_TexCoord2f32(gx->overlay[i].tex_coord[6], gx->overlay[i].tex_coord[7]); GX_End(); } GX_SetVtxDesc(GX_VA_POS, GX_INDEX8); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX8); - - /*if (gx->overlay_full_screen) - glViewport(gx->vp.x, gx->vp.y, gx->vp.width, gx->vp.height);*/ + GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8); } static const video_overlay_interface_t gx_overlay_interface = {