aboutsummaryrefslogtreecommitdiff
path: root/frontend
diff options
context:
space:
mode:
authornotaz2012-11-18 00:31:30 +0200
committernotaz2012-11-18 01:40:00 +0200
commitc9099d020a1e523d97541f426f7d44da1392526f (patch)
tree10ff6a0e5cad146d8e139530e5bc7be197d6ae65 /frontend
parenta83762012066e4799394f63d08a161a45f982ab6 (diff)
downloadpcsx_rearmed-c9099d020a1e523d97541f426f7d44da1392526f.tar.gz
pcsx_rearmed-c9099d020a1e523d97541f426f7d44da1392526f.tar.bz2
pcsx_rearmed-c9099d020a1e523d97541f426f7d44da1392526f.zip
frontend: overlay improvements
work directly on psx vram
Diffstat (limited to 'frontend')
m---------frontend/libpicofe0
-rw-r--r--frontend/main.c4
-rw-r--r--frontend/plat_sdl.c137
-rw-r--r--frontend/plugin_lib.c83
-rw-r--r--frontend/plugin_lib.h6
5 files changed, 160 insertions, 70 deletions
diff --git a/frontend/libpicofe b/frontend/libpicofe
-Subproject 9227a7770e0d144109ee34ae34a270c6d06b9f8
+Subproject 3e1124f989febba80ef582c1200153ed176226f
diff --git a/frontend/main.c b/frontend/main.c
index 29df6d9..f5da18b 100644
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -263,6 +263,10 @@ do_state_slot:
break;
case SACTION_TOGGLE_FULLSCREEN:
g_fullscreen = !g_fullscreen;
+ if (GPU_open != NULL && GPU_close != NULL) {
+ GPU_close();
+ GPU_open(&gpuDisp, "PCSX", NULL);
+ }
break;
case SACTION_SCREENSHOT:
{
diff --git a/frontend/plat_sdl.c b/frontend/plat_sdl.c
index a899c15..3661149 100644
--- a/frontend/plat_sdl.c
+++ b/frontend/plat_sdl.c
@@ -14,6 +14,8 @@
#include "libpicofe/input.h"
#include "libpicofe/in_sdl.h"
#include "libpicofe/menu.h"
+#include "libpicofe/fonts.h"
+#include "../plugins/gpulib/cspace.h"
#include "plugin_lib.h"
#include "main.h"
#include "menu.h"
@@ -58,7 +60,9 @@ static int window_w, window_h;
static int fs_w, fs_h;
static int psx_w, psx_h;
static void *menubg_img;
-static int in_menu, pending_resize, old_fullscreen;
+static int in_menu, old_fullscreen;
+
+static void overlay_clear(void);
static int change_video_mode(int w, int h)
{
@@ -98,6 +102,8 @@ static int change_video_mode(int w, int h)
if (!overlay->hw_overlay)
fprintf(stderr, "warning: video overlay is not hardware accelerated,"
" you may want to disable it.\n");
+
+ overlay_clear();
}
else {
fprintf(stderr, "warning: could not create overlay.\n");
@@ -130,7 +136,7 @@ static void event_handler(void *event_)
if (overlay != NULL && !g_fullscreen && !old_fullscreen) {
window_w = event->resize.w;
window_h = event->resize.h;
- pending_resize = 1;
+ change_video_mode(psx_w, psx_h);
}
}
}
@@ -189,6 +195,8 @@ void plat_init(void)
in_sdl_init(in_sdl_defbinds, event_handler);
in_probe();
pl_rearmed_cbs.only_16bpp = 1;
+
+ bgr_to_uyvy_init();
return;
fail:
@@ -207,65 +215,96 @@ void plat_gvideo_open(int is_pal)
{
}
-void *plat_gvideo_set_mode(int *w, int *h, int *bpp)
+static void uyvy_to_rgb565(void *d, const void *s, int pixels)
{
- change_video_mode(*w, *h);
- return screen->pixels;
+ unsigned short *dst = d;
+ const unsigned int *src = s;
+ int v;
+
+ // no colors, for now
+ for (; pixels > 0; src++, dst += 2, pixels -= 2) {
+ v = (*src >> 8) & 0xff;
+ v = (v - 16) * 255 / 219 / 8;
+ dst[0] = (v << 11) | (v << 6) | v;
+
+ v = (*src >> 24) & 0xff;
+ v = (v - 16) * 255 / 219 / 8;
+ dst[1] = (v << 11) | (v << 6) | v;
+ }
}
-static void test_convert(void *d, const void *s, int pixels)
+static void overlay_clear(void)
{
- unsigned int *dst = d;
- const unsigned short *src = s;
- int r0, g0, b0, r1, g1, b1;
- int y0, y1, u, v;
-
- for (; pixels > 0; src += 2, dst++, pixels -= 2) {
- r0 = src[0] >> 11;
- g0 = (src[0] >> 6) & 0x1f;
- b0 = src[0] & 0x1f;
- r1 = src[1] >> 11;
- g1 = (src[1] >> 6) & 0x1f;
- b1 = src[1] & 0x1f;
- y0 = (int)((0.299f * r0) + (0.587f * g0) + (0.114f * b0));
- y1 = (int)((0.299f * r1) + (0.587f * g1) + (0.114f * b1));
- //u = (int)(((-0.169f * r0) + (-0.331f * g0) + ( 0.499f * b0)) * 8) + 128;
- //v = (int)((( 0.499f * r0) + (-0.418f * g0) + (-0.0813f * b0)) * 8) + 128;
- u = (int)(8 * 0.565f * (b0 - y0)) + 128;
- v = (int)(8 * 0.713f * (r0 - y0)) + 128;
- // valid Y range seems to be 16..235
- y0 = 16 + 219 * y0 / 31;
- y1 = 16 + 219 * y1 / 31;
-
- if (y0 < 0 || y0 > 255 || y1 < 0 || y1 > 255
- || u < 0 || u > 255 || v < 0 || v > 255)
- {
- printf("oor: %d, %d, %d, %d\n", y0, y1, u, v);
- }
- *dst = (y1 << 24) | (v << 16) | (y0 << 8) | u;
+ int pixels = overlay->w * overlay->h;
+ int *dst = (int *)overlay->pixels[0];
+ int v = 0x10801080;
+
+ for (; pixels > 0; dst += 4, pixels -= 2 * 4)
+ dst[0] = dst[1] = dst[2] = dst[3] = v;
+
+ for (; pixels > 0; dst++, pixels -= 2)
+ *dst = v;
+}
+
+static void overlay_blit(int doffs, const void *src_, int w, int h,
+ int sstride, int bgr24)
+{
+ const unsigned short *src = src_;
+ unsigned short *dst;
+ int dstride = overlay->w;
+
+ SDL_LockYUVOverlay(overlay);
+ dst = (void *)overlay->pixels[0];
+
+ dst += doffs;
+ if (bgr24) {
+ for (; h > 0; dst += dstride, src += sstride, h--)
+ bgr888_to_uyvy(dst, src, w);
+ }
+ else {
+ for (; h > 0; dst += dstride, src += sstride, h--)
+ bgr555_to_uyvy(dst, src, w);
+ }
+
+ SDL_UnlockYUVOverlay(overlay);
+}
+
+static void overlay_hud_print(int x, int y, const char *str, int bpp)
+{
+ SDL_LockYUVOverlay(overlay);
+ basic_text_out_uyvy_nf(overlay->pixels[0], overlay->w, x, y, str);
+ SDL_UnlockYUVOverlay(overlay);
+}
+
+void *plat_gvideo_set_mode(int *w, int *h, int *bpp)
+{
+ change_video_mode(*w, *h);
+ if (overlay != NULL) {
+ pl_plat_clear = overlay_clear;
+ pl_plat_blit = overlay_blit;
+ pl_plat_hud_print = overlay_hud_print;
+ return NULL;
+ }
+ else {
+ pl_plat_clear = NULL;
+ pl_plat_blit = NULL;
+ pl_plat_hud_print = NULL;
+ return screen->pixels;
}
}
-/* XXX: missing SDL_LockSurface() */
void *plat_gvideo_flip(void)
{
if (!in_menu && overlay != NULL) {
SDL_Rect dstrect = { 0, 0, screen->w, screen->h };
- SDL_LockYUVOverlay(overlay);
- test_convert(overlay->pixels[0], screen->pixels, overlay->w * overlay->h);
- SDL_UnlockYUVOverlay(overlay);
SDL_DisplayYUVOverlay(overlay, &dstrect);
+ return NULL;
}
- else
+ else {
+ // XXX: missing SDL_LockSurface()
SDL_Flip(screen);
-
- if (pending_resize || g_fullscreen != old_fullscreen) {
- // must be done here so that correct buffer is returned
- change_video_mode(psx_w, psx_h);
- pending_resize = 0;
+ return screen->pixels;
}
-
- return screen->pixels;
}
void plat_gvideo_close(void)
@@ -277,8 +316,10 @@ void plat_video_menu_enter(int is_rom_loaded)
in_menu = 1;
/* surface will be lost, must adjust pl_vout_buf for menu bg */
- // FIXME?
- memcpy(menubg_img, screen->pixels, psx_w * psx_h * 2);
+ if (overlay != NULL)
+ uyvy_to_rgb565(menubg_img, overlay->pixels[0], psx_w * psx_h);
+ else
+ memcpy(menubg_img, screen->pixels, psx_w * psx_h * 2);
pl_vout_buf = menubg_img;
change_video_mode(g_menuscreen_w, g_menuscreen_h);
diff --git a/frontend/plugin_lib.c b/frontend/plugin_lib.c
index 9cbfe59..a0f16e9 100644
--- a/frontend/plugin_lib.c
+++ b/frontend/plugin_lib.c
@@ -49,6 +49,12 @@ static int vsync_cnt;
static int is_pal, frame_interval, frame_interval1024;
static int vsync_usec_time;
+// platform hooks
+void (*pl_plat_clear)(void);
+void (*pl_plat_blit)(int doffs, const void *src, int w, int h,
+ int sstride, int bgr24);
+void (*pl_plat_hud_print)(int x, int y, const char *str, int bpp);
+
static __attribute__((noinline)) int get_cpu_ticks(void)
{
@@ -66,31 +72,48 @@ static __attribute__((noinline)) int get_cpu_ticks(void)
sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu", &utime);
ret = utime - last_utime;
+ if (ret > 200)
+ ret = 0;
last_utime = utime;
return ret;
}
+static void hud_print(void *fb, int w, int x, int y, const char *text)
+{
+ if (pl_plat_hud_print)
+ pl_plat_hud_print(x, y, text, pl_vout_bpp);
+ else if (pl_vout_bpp == 16)
+ basic_text_out16_nf(fb, w, x, y, text);
+}
+
+static void hud_printf(void *fb, int w, int x, int y, const char *texto, ...)
+{
+ va_list args;
+ char buffer[256];
+
+ va_start(args, texto);
+ vsnprintf(buffer, sizeof(buffer), texto, args);
+ va_end(args);
+
+ hud_print(fb, w, x, y, buffer);
+}
+
static void print_msg(int h, int border)
{
- if (pl_vout_bpp == 16)
- basic_text_out16_nf(pl_vout_buf, pl_vout_w,
- border + 2, h - 10, hud_msg);
+ hud_print(pl_vout_buf, pl_vout_w, border + 2, h - 10, hud_msg);
}
static void print_fps(int h, int border)
{
- if (pl_vout_bpp == 16)
- basic_text_out16(pl_vout_buf, pl_vout_w,
- border + 2, h - 10, "%2d %4.1f",
- pl_rearmed_cbs.flips_per_sec, pl_rearmed_cbs.vsps_cur);
+ hud_printf(pl_vout_buf, pl_vout_w, border + 2, h - 10,
+ "%2d %4.1f", pl_rearmed_cbs.flips_per_sec,
+ pl_rearmed_cbs.vsps_cur);
}
static void print_cpu_usage(int w, int h, int border)
{
- if (pl_vout_bpp == 16)
- basic_text_out16(pl_vout_buf, pl_vout_w,
- pl_vout_w - border - 28, h - 10,
- "%3d", pl_rearmed_cbs.cpu_usage);
+ hud_printf(pl_vout_buf, pl_vout_w, pl_vout_w - border - 28, h - 10,
+ "%3d", pl_rearmed_cbs.cpu_usage);
}
// draw 192x8 status of 24 sound channels
@@ -106,7 +129,7 @@ static __attribute__((noinline)) void draw_active_chans(int vout_w, int vout_h)
unsigned short *d, p;
int c, x, y;
- if (pl_vout_bpp != 16)
+ if (dest == NULL || pl_vout_bpp != 16)
return;
spu_get_debug_info(&live_chans, &run_chans, &fmod_chans, &noise_chans);
@@ -238,7 +261,7 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
update_layer_size(vout_w, vout_h);
pl_vout_buf = plat_gvideo_set_mode(&vout_w, &vout_h, &vout_bpp);
- if (pl_vout_buf == NULL)
+ if (pl_vout_buf == NULL && pl_plat_blit == NULL)
fprintf(stderr, "failed to set mode %dx%d@%d\n",
vout_w, vout_h, psx_bpp);
else {
@@ -260,28 +283,43 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, int w, int h)
pcnt_start(PCNT_BLIT);
- if (dest == NULL)
- goto out;
-
if (vram == NULL) {
// blanking
- memset(pl_vout_buf, 0, dstride * pl_vout_h * pl_vout_bpp / 8);
- goto out;
+ if (pl_plat_clear)
+ pl_plat_clear();
+ else
+ memset(pl_vout_buf, 0,
+ dstride * pl_vout_h * pl_vout_bpp / 8);
+ goto out_hud;
}
// borders
doffs = (dstride - w * pl_vout_scale) / 2 & ~1;
- dest += doffs * 2;
if (doffs > doffs_old)
clear_counter = 2;
doffs_old = doffs;
if (clear_counter > 0) {
- memset(pl_vout_buf, 0, dstride * pl_vout_h * pl_vout_bpp / 8);
+ if (pl_plat_clear)
+ pl_plat_clear();
+ else
+ memset(pl_vout_buf, 0,
+ dstride * pl_vout_h * pl_vout_bpp / 8);
clear_counter--;
}
+ if (pl_plat_blit)
+ {
+ pl_plat_blit(doffs, src, w, h, stride, bgr24);
+ goto out_hud;
+ }
+
+ if (dest == NULL)
+ goto out;
+
+ dest += doffs * 2;
+
if (bgr24)
{
if (pl_rearmed_cbs.only_16bpp) {
@@ -304,12 +342,12 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, int w, int h)
else if (soft_filter == SOFT_FILTER_SCALE2X && pl_vout_scale == 2)
{
neon_scale2x_16_16(src, (void *)dest, w,
- stride * 2, dstride * 2, h1);
+ stride * 2, dstride * 2, h);
}
else if (soft_filter == SOFT_FILTER_EAGLE2X && pl_vout_scale == 2)
{
neon_eagle2x_16_16(src, (void *)dest, w,
- stride * 2, dstride * 2, h1);
+ stride * 2, dstride * 2, h);
}
#endif
else
@@ -320,6 +358,7 @@ static void pl_vout_flip(const void *vram, int stride, int bgr24, int w, int h)
}
}
+out_hud:
pl_print_hud(w * pl_vout_scale, h * pl_vout_scale, 0);
out:
diff --git a/frontend/plugin_lib.h b/frontend/plugin_lib.h
index 2f6c680..bec16b2 100644
--- a/frontend/plugin_lib.h
+++ b/frontend/plugin_lib.h
@@ -93,6 +93,12 @@ enum gpu_plugin_caps {
GPU_CAP_SUPPORTS_2X = (1 << 1),
};
+// platform hooks
+extern void (*pl_plat_clear)(void);
+extern void (*pl_plat_blit)(int doffs, const void *src,
+ int w, int h, int sstride, int bgr24);
+extern void (*pl_plat_hud_print)(int x, int y, const char *str, int bpp);
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#endif