sdandalone: rework sdl output
authornotaz <notasas@gmail.com>
Sat, 10 May 2025 22:21:51 +0000 (01:21 +0300)
committernotaz <notasas@gmail.com>
Sun, 11 May 2025 23:25:10 +0000 (02:25 +0300)
- 2x overlay mode from PicoDrive
- somewhat proper fullscreen mode
- overlay scaling options
- gles mode probably broken (no longer works on more modern distros
  anyway - it's some very old code)
- new bugs

Makefile
frontend/cspace.c
frontend/cspace.h
frontend/libpicofe
frontend/menu.c
frontend/pandora/ui_feat.h
frontend/plat_sdl.c
frontend/plugin_lib.c
frontend/plugin_lib.h

index 7d76d21..f56ca1a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -363,9 +363,11 @@ endif
 
 ifeq "$(PLATFORM)" "generic"
 OBJS += frontend/libpicofe/in_sdl.o
-OBJS += frontend/libpicofe/plat_sdl.o
+#OBJS += frontend/libpicofe/plat_sdl.o
 OBJS += frontend/libpicofe/plat_dummy.o
 OBJS += frontend/plat_sdl.o
+frontend/plat_sdl.o frontend/libpicofe/plat_sdl.o: CFLAGS += -DSDL_OVERLAY_2X
+frontend/menu.o: CFLAGS += -DSDL_OVERLAY_2X -DMENU_SHOW_VARSCALER=1
 ifeq "$(HAVE_EVDEV)" "1"
 OBJS += frontend/libpicofe/linux/in_evdev.o
 endif
@@ -387,6 +389,7 @@ OBJS += frontend/libpicofe/linux/in_evdev.o
 OBJS += frontend/plat_pandora.o frontend/plat_omap.o
 frontend/main.o frontend/menu.o: CFLAGS += -include frontend/pandora/ui_feat.h
 frontend/libpicofe/linux/plat.o: CFLAGS += -DPANDORA
+frontend/plugin_lib.o: CFLAGS += -DPANDORA
 USE_PLUGIN_LIB = 1
 USE_FRONTEND = 1
 CFLAGS += -gdwarf-3
index 3a09792..8249f80 100644 (file)
@@ -168,36 +168,53 @@ void bgr888_to_xrgb8888(void * __restrict__ dst_, const void * __restrict__ src_
 /* YUV stuff */
 static int yuv_ry[32], yuv_gy[32], yuv_by[32];
 static unsigned char yuv_u[32 * 2], yuv_v[32 * 2];
+static struct uyvy { uint32_t y:8; uint32_t vyu:24; } yuv_uyvy[32768];
 
 void bgr_to_uyvy_init(void)
 {
-  int i, v;
-
-  /* init yuv converter:
-    y0 = (int)((0.299f * r0) + (0.587f * g0) + (0.114f * b0));
-    y1 = (int)((0.299f * r1) + (0.587f * g1) + (0.114f * b1));
-    u = (int)(8 * 0.565f * (b0 - y0)) + 128;
-    v = (int)(8 * 0.713f * (r0 - y0)) + 128;
-  */
-  for (i = 0; i < 32; i++) {
-    yuv_ry[i] = (int)(0.299f * i * 65536.0f + 0.5f);
-    yuv_gy[i] = (int)(0.587f * i * 65536.0f + 0.5f);
-    yuv_by[i] = (int)(0.114f * i * 65536.0f + 0.5f);
-  }
-  for (i = -32; i < 32; i++) {
-    v = (int)(8 * 0.565f * i) + 128;
-    if (v < 0)
-      v = 0;
-    if (v > 255)
-      v = 255;
-    yuv_u[i + 32] = v;
-    v = (int)(8 * 0.713f * i) + 128;
-    if (v < 0)
-      v = 0;
-    if (v > 255)
-      v = 255;
-    yuv_v[i + 32] = v;
-  }
+       unsigned char yuv_y[256];
+       int i, v;
+
+       /* init yuv converter:
+          y0 = (int)((0.299f * r0) + (0.587f * g0) + (0.114f * b0));
+          y1 = (int)((0.299f * r1) + (0.587f * g1) + (0.114f * b1));
+          u = (int)(8 * 0.565f * (b0 - y0)) + 128;
+          v = (int)(8 * 0.713f * (r0 - y0)) + 128;
+          */
+       for (i = 0; i < 32; i++) {
+               yuv_ry[i] = (int)(0.299f * i * 65536.0f + 0.5f);
+               yuv_gy[i] = (int)(0.587f * i * 65536.0f + 0.5f);
+               yuv_by[i] = (int)(0.114f * i * 65536.0f + 0.5f);
+       }
+       for (i = -32; i < 32; i++) {
+               v = (int)(8 * 0.565f * i) + 128;
+               if (v < 0)
+                       v = 0;
+               if (v > 255)
+                       v = 255;
+               yuv_u[i + 32] = v;
+               v = (int)(8 * 0.713f * i) + 128;
+               if (v < 0)
+                       v = 0;
+               if (v > 255)
+                       v = 255;
+               yuv_v[i + 32] = v;
+       }
+       // valid Y range seems to be 16..235
+       for (i = 0; i < 256; i++) {
+               yuv_y[i] = 16 + 219 * i / 32;
+       }
+       // everything combined into one large array for speed
+       for (i = 0; i < 32768; i++) {
+               int r = (i >> 0) & 0x1f, g = (i >> 5) & 0x1f, b = (i >> 10) & 0x1f;
+               int y = (yuv_ry[r] + yuv_gy[g] + yuv_by[b]) >> 16;
+               yuv_uyvy[i].y = yuv_y[y];
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+               yuv_uyvy[i].vyu = (yuv_v[b-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[r-y + 32];
+#else
+               yuv_uyvy[i].vyu = (yuv_v[r-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[b-y + 32];
+#endif
+       }
 }
 
 void rgb565_to_uyvy(void *d, const void *s, int pixels)
@@ -229,54 +246,89 @@ void rgb565_to_uyvy(void *d, const void *s, int pixels)
   }
 }
 
-void bgr555_to_uyvy(void *d, const void *s, int pixels)
+void bgr555_to_uyvy(void *d, const void *s, int pixels, int x2)
 {
-  unsigned int *dst = d;
-  const unsigned short *src = s;
-  const unsigned char *yu = yuv_u + 32;
-  const unsigned char *yv = yuv_v + 32;
-  int r0, g0, b0, r1, g1, b1;
-  int y0, y1, u, v;
-
-  for (; pixels > 1; src += 2, dst++, pixels -= 2)
-  {
-    b0 = (src[0] >> 10) & 0x1f;
-    g0 = (src[0] >> 5) & 0x1f;
-    r0 =  src[0] & 0x1f;
-    b1 = (src[1] >> 10) & 0x1f;
-    g1 = (src[1] >> 5) & 0x1f;
-    r1 =  src[1] & 0x1f;
-    y0 = (yuv_ry[r0] + yuv_gy[g0] + yuv_by[b0]) >> 16;
-    y1 = (yuv_ry[r1] + yuv_gy[g1] + yuv_by[b1]) >> 16;
-    u = yu[b0 - y0];
-    v = yv[r0 - y0];
-    y0 = 16 + 219 * y0 / 31;
-    y1 = 16 + 219 * y1 / 31;
-
-    *dst = (y1 << 24) | (v << 16) | (y0 << 8) | u;
-  }
+       uint32_t *dst = d;
+       const uint16_t *src = s;
+       int i;
+
+       if (x2) {
+               for (i = pixels; i >= 4; src += 4, dst += 4, i -= 4)
+               {
+                       const struct uyvy *uyvy0 = yuv_uyvy + (src[0] & 0x7fff);
+                       const struct uyvy *uyvy1 = yuv_uyvy + (src[1] & 0x7fff);
+                       const struct uyvy *uyvy2 = yuv_uyvy + (src[2] & 0x7fff);
+                       const struct uyvy *uyvy3 = yuv_uyvy + (src[3] & 0x7fff);
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+                       dst[0] = uyvy0->y | (uyvy0->vyu << 8);
+                       dst[1] = uyvy1->y | (uyvy1->vyu << 8);
+                       dst[2] = uyvy2->y | (uyvy2->vyu << 8);
+                       dst[3] = uyvy3->y | (uyvy3->vyu << 8);
+#else
+                       dst[0] = (uyvy0->y << 24) | uyvy0->vyu;
+                       dst[1] = (uyvy1->y << 24) | uyvy1->vyu;
+                       dst[2] = (uyvy2->y << 24) | uyvy2->vyu;
+                       dst[3] = (uyvy3->y << 24) | uyvy3->vyu;
+#endif
+               }
+       } else {
+               for (i = pixels; i >= 4; src += 4, dst += 2, i -= 4)
+               {
+                       const struct uyvy *uyvy0 = yuv_uyvy + (src[0] & 0x7fff);
+                       const struct uyvy *uyvy1 = yuv_uyvy + (src[1] & 0x7fff);
+                       const struct uyvy *uyvy2 = yuv_uyvy + (src[2] & 0x7fff);
+                       const struct uyvy *uyvy3 = yuv_uyvy + (src[3] & 0x7fff);
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+                       dst[0] = uyvy1->y | (uyvy0->vyu << 8);
+                       dst[1] = uyvy3->y | (uyvy2->vyu << 8);
+#else
+                       dst[0] = (uyvy1->y << 24) | uyvy0->vyu;
+                       dst[1] = (uyvy3->y << 24) | uyvy2->vyu;
+#endif
+               }
+       }
 }
 
-void bgr888_to_uyvy(void *d, const void *s, int pixels)
+void bgr888_to_uyvy(void *d, const void *s, int pixels, int x2)
 {
-  unsigned int *dst = d;
-  const unsigned char *src8 = s;
-  const unsigned char *yu = yuv_u + 32;
-  const unsigned char *yv = yuv_v + 32;
-  int r0, g0, b0, r1, g1, b1;
-  int y0, y1, u, v;
-
-  for (; pixels > 0; src8 += 3*2, dst++, pixels -= 2)
-  {
-    r0 = src8[0], g0 = src8[1], b0 = src8[2];
-    r1 = src8[3], g1 = src8[4], b1 = src8[5];
-    y0 = (r0 * 19595 + g0 * 38470 + b0 * 7471) >> 16;
-    y1 = (r1 * 19595 + g1 * 38470 + b1 * 7471) >> 16;
-    u = yu[(b0 - y0) / 8];
-    v = yv[(r0 - y0) / 8];
-    y0 = 16 + 219 * y0 / 255;
-    y1 = 16 + 219 * y1 / 255;
-
-    *dst = (y1 << 24) | (v << 16) | (y0 << 8) | u;
-  }
+       unsigned int *dst = d;
+       const unsigned char *src8 = s;
+       const unsigned char *yu = yuv_u + 32;
+       const unsigned char *yv = yuv_v + 32;
+       int r0, g0, b0, r1, g1, b1;
+       int y0, y1, u0, u1, v0, v1;
+
+       if (x2) {
+               for (; pixels >= 2; src8 += 3*2, pixels -= 2)
+               {
+                       r0 = src8[0], g0 = src8[1], b0 = src8[2];
+                       r1 = src8[3], g1 = src8[4], b1 = src8[5];
+                       y0 = (r0 * 19595 + g0 * 38470 + b0 * 7471) >> 16;
+                       y1 = (r1 * 19595 + g1 * 38470 + b1 * 7471) >> 16;
+                       u0 = yu[(b0 - y0) / 8];
+                       u1 = yu[(b1 - y1) / 8];
+                       v0 = yv[(r0 - y0) / 8];
+                       v1 = yv[(r1 - y1) / 8];
+                       y0 = 16 + 219 * y0 / 255;
+                       y1 = 16 + 219 * y1 / 255;
+
+                       *dst++ = (y0 << 24) | (v0 << 16) | (y0 << 8) | u0;
+                       *dst++ = (y1 << 24) | (v1 << 16) | (y1 << 8) | u1;
+               }
+       }
+       else {
+               for (; pixels >= 2; src8 += 3*2, dst++, pixels -= 2)
+               {
+                       r0 = src8[0], g0 = src8[1], b0 = src8[2];
+                       r1 = src8[3], g1 = src8[4], b1 = src8[5];
+                       y0 = (r0 * 19595 + g0 * 38470 + b0 * 7471) >> 16;
+                       y1 = (r1 * 19595 + g1 * 38470 + b1 * 7471) >> 16;
+                       u0 = yu[(b0 - y0) / 8];
+                       v0 = yv[(r0 - y0) / 8];
+                       y0 = 16 + 219 * y0 / 255;
+                       y1 = 16 + 219 * y1 / 255;
+
+                       *dst = (y1 << 24) | (v0 << 16) | (y0 << 8) | u0;
+               }
+       }
 }
index 61bddf9..e593196 100644 (file)
@@ -19,8 +19,8 @@ void bgr888_to_xrgb8888(void *dst, const void *src, int bytes);
 
 void bgr_to_uyvy_init(void);
 void rgb565_to_uyvy(void *d, const void *s, int pixels);
-void bgr555_to_uyvy(void *d, const void *s, int pixels);
-void bgr888_to_uyvy(void *d, const void *s, int pixels);
+void bgr555_to_uyvy(void *d, const void *s, int pixels, int x2);
+void bgr888_to_uyvy(void *d, const void *s, int pixels, int x2);
 
 #ifdef __cplusplus
 }
index a8ded55..80612f5 160000 (submodule)
@@ -1 +1 @@
-Subproject commit a8ded55fc9df952b5582a6da72e1de887e65a34b
+Subproject commit 80612f5f31a3201e6c7f710109a9c8b48f6bb757
index 99ca592..a5ffb7b 100644 (file)
@@ -94,6 +94,7 @@ typedef enum
        MA_OPT_SWFILTER,
        MA_OPT_GAMMA,
        MA_OPT_VOUT_MODE,
+       MA_OPT_VOUT_FULL,
        MA_OPT_SCANLINES,
        MA_OPT_SCANLINE_LEVEL,
        MA_OPT_CENTERING,
@@ -132,7 +133,6 @@ static int bios_sel, gpu_plugsel, spu_plugsel;
 
 #ifndef UI_FEATURES_H
 #define MENU_BIOS_PATH "bios/"
-#define MENU_SHOW_VARSCALER 0
 #define MENU_SHOW_VOUTMODE 1
 #define MENU_SHOW_SCALER2 0
 #define MENU_SHOW_NUBS_BTNS 0
@@ -142,6 +142,12 @@ static int bios_sel, gpu_plugsel, spu_plugsel;
 #define MENU_SHOW_FULLSCREEN 1
 #define MENU_SHOW_VOLUME 0
 #endif
+#ifndef MENU_SHOW_VARSCALER
+#define MENU_SHOW_VARSCALER 0
+#endif
+#ifndef MENU_SHOW_VARSCALER_C
+#define MENU_SHOW_VARSCALER_C 0
+#endif
 
 static int min(int x, int y) { return x < y ? x : y; }
 static int max(int x, int y) { return x > y ? x : y; }
@@ -1280,7 +1286,11 @@ static int menu_loop_keyconfig(int id, int keys)
 // ------------ gfx options menu ------------
 
 static const char *men_scaler[] = {
-       "1x1", "integer scaled 2x", "scaled 4:3", "integer scaled 4:3", "fullscreen", "custom", NULL
+       "1x1", "integer scaled 2x", "scaled 4:3", "integer scaled 4:3", "fullscreen",
+#if MENU_SHOW_VARSCALER_C
+       "custom",
+#endif
+       NULL
 };
 static const char *men_soft_filter[] = { "None",
 #ifdef HAVE_NEON32
@@ -1385,10 +1395,11 @@ static int menu_loop_cscaler(int id, int keys)
 
 static menu_entry e_menu_gfx_options[] =
 {
-       mee_enum      ("Screen centering",         MA_OPT_CENTERING, pl_rearmed_cbs.screen_centering_type, men_centering),
+       mee_enum      ("PSX Screen centering",     MA_OPT_CENTERING, pl_rearmed_cbs.screen_centering_type, men_centering),
        mee_enum      ("Show overscan",            MA_OPT_OVERSCAN, pl_rearmed_cbs.show_overscan, men_overscan),
        mee_enum_h    ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler, h_scaler),
        mee_enum      ("Video output mode",        MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
+       mee_onoff     ("Fullscreen mode",          MA_OPT_VOUT_FULL, plat_target.vout_fullscreen, 1),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
        mee_enum      ("Hardware Filter",          MA_OPT_HWFILTER, plat_target.hwfilter, men_dummy),
        mee_enum_h    ("Software Filter",          MA_OPT_SWFILTER, soft_filter, men_soft_filter, h_soft_filter),
@@ -2672,6 +2683,12 @@ void menu_init(void)
        me_enable(e_menu_gfx_options, MA_OPT_VOUT_MODE,
                plat_target.vout_methods != NULL);
 
+#ifndef SDL_OVERLAY_2X
+       i = me_id2offset(e_menu_gfx_options, MA_OPT_VOUT_FULL);
+       e_menu_gfx_options[i].data = plat_target.vout_methods;
+       me_enable(e_menu_gfx_options, MA_OPT_VOUT_FULL, 0);
+#endif
+
        i = me_id2offset(e_menu_gfx_options, MA_OPT_HWFILTER);
        e_menu_gfx_options[i].data = plat_target.hwfilters;
        me_enable(e_menu_gfx_options, MA_OPT_HWFILTER,
@@ -2685,7 +2702,7 @@ void menu_init(void)
 #endif
        me_enable(e_menu_gfx_options, MA_OPT_VARSCALER, MENU_SHOW_VARSCALER);
        me_enable(e_menu_gfx_options, MA_OPT_VOUT_MODE, MENU_SHOW_VOUTMODE);
-       me_enable(e_menu_gfx_options, MA_OPT_VARSCALER_C, MENU_SHOW_VARSCALER);
+       me_enable(e_menu_gfx_options, MA_OPT_VARSCALER_C, MENU_SHOW_VARSCALER_C);
        me_enable(e_menu_gfx_options, MA_OPT_SCALER2, MENU_SHOW_SCALER2);
        me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, MENU_SHOW_NUBS_BTNS);
        me_enable(e_menu_keyconfig, MA_CTRL_VIBRATION, MENU_SHOW_VIBRATION);
index 3bb808a..5eb3dc2 100644 (file)
@@ -4,6 +4,7 @@
 #define MENU_BIOS_PATH "<SD card>/pandora/appdata/pcsx_rearmed/bios/"
 #define BOOT_MSG "Booting up...  (press SPACE for menu)"
 #define MENU_SHOW_VARSCALER 1
+#define MENU_SHOW_VARSCALER_C 1
 #define MENU_SHOW_VOUTMODE 0
 #define MENU_SHOW_SCALER2 0
 #define MENU_SHOW_NUBS_BTNS 1
index 64cac7c..3529d97 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <stdio.h>
+#include <assert.h>
 #include <SDL.h>
 
 #include "libpicofe/input.h"
 #include "libpicofe/menu.h"
 #include "libpicofe/fonts.h"
 #include "libpicofe/plat_sdl.h"
+#include "libpicofe/plat.h"
 #include "libpicofe/gl.h"
 #include "cspace.h"
 #include "plugin_lib.h"
 #include "plugin.h"
+#include "menu.h"
 #include "main.h"
 #include "plat.h"
 #include "revision.h"
 
+#include "libpicofe/plat_sdl.c"
+
 static const struct in_default_bind in_sdl_defbinds[] = {
   { SDLK_UP,     IN_BINDTYPE_PLAYER12, DKEY_UP },
   { SDLK_DOWN,   IN_BINDTYPE_PLAYER12, DKEY_DOWN },
@@ -90,39 +95,45 @@ static const struct in_pdata in_sdl_platform_data = {
 
 static int psx_w = 256, psx_h = 240;
 static void *shadow_fb, *menubg_img;
+static int resized, window_w, window_h;
+static int vout_fullscreen_old;
+static int forced_clears;
+static int forced_flips;
+static int sdl12_compat;
 static int in_menu;
 
+static void handle_scaler_resize(int w, int h);
 static void centered_clear(void);
-static void *setup_blit_callbacks(int w);
-
-static int change_video_mode(int force)
-{
-  int w, h, ret;
-
-  if (in_menu) {
-    w = g_menuscreen_w;
-    h = g_menuscreen_h;
-  }
-  else {
-    w = psx_w;
-    h = psx_h;
-  }
-
-  ret = plat_sdl_change_video_mode(w, h, force);
-  if (ret == 0 && plat_sdl_overlay == NULL && !plat_sdl_gl_active)
-    centered_clear();
-  return ret;
-}
 
 static void resize_cb(int w, int h)
 {
-  // used by some plugins..
+  // used by some plugins...
   pl_rearmed_cbs.screen_w = w;
   pl_rearmed_cbs.screen_h = h;
   pl_rearmed_cbs.gles_display = gl_es_display;
   pl_rearmed_cbs.gles_surface = gl_es_surface;
   plugin_call_rearmed_cbs();
-  setup_blit_callbacks(psx_w);
+}
+
+static void sdl_event_handler(void *event_)
+{
+  SDL_Event *event = event_;
+
+  switch (event->type) {
+  case SDL_VIDEORESIZE:
+    if (window_w != (event->resize.w & ~3) || window_h != (event->resize.h & ~1)) {
+      window_w = event->resize.w & ~3;
+      window_h = event->resize.h & ~1;
+      resized = 1;
+    }
+    return;
+  case SDL_ACTIVEEVENT:
+    // no need to redraw?
+    return;
+  default:
+    break;
+  }
+  plat_sdl_event_handler(event_);
 }
 
 static void quit_cb(void)
@@ -140,6 +151,7 @@ static void get_layer_pos(int *x, int *y, int *w, int *h)
 
 void plat_init(void)
 {
+  const SDL_version *ver;
   int shadow_size;
   int ret;
 
@@ -150,6 +162,10 @@ void plat_init(void)
   if (ret != 0)
     exit(1);
 
+  ver = SDL_Linked_Version();
+  sdl12_compat = ver->patch >= 50;
+  printf("SDL %u.%u.%u compat=%d\n", ver->major, ver->minor, ver->patch, sdl12_compat);
+
   in_menu = 1;
   SDL_WM_SetCaption("PCSX-ReARMed " REV, NULL);
 
@@ -165,12 +181,19 @@ void plat_init(void)
     exit(1);
   }
 
-  in_sdl_init(&in_sdl_platform_data, plat_sdl_event_handler);
+  in_sdl_init(&in_sdl_platform_data, sdl_event_handler);
   in_probe();
   pl_rearmed_cbs.only_16bpp = 1;
   pl_rearmed_cbs.pl_get_layer_pos = get_layer_pos;
 
   bgr_to_uyvy_init();
+
+  // to "finish" init and set SDL_RESIZABLE
+  plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, -1);
+  if (plat_sdl_overlay) {
+    printf("overlay: %08x hw=%d\n", plat_sdl_overlay->format,
+        plat_sdl_overlay->hw_overlay);
+  }
 }
 
 void plat_finish(void)
@@ -186,22 +209,70 @@ void plat_gvideo_open(int is_pal)
 {
 }
 
-static void uyvy_to_rgb565(void *d, const void *s, int pixels)
+static void uyvy_to_rgb565(void *d, int pixels)
 {
+  const unsigned int *src = (const void *)plat_sdl_overlay->pixels[0];
+  int x2 = plat_sdl_overlay->w >= psx_w * 2;
   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;
+  if (x2) {
+    for (; pixels > 0; src++, dst++, pixels--) {
+      v = (*src >> 8) & 0xff;
+      v = (v - 16) * 255 / 219 / 8;
+      *dst = (v << 11) | (v << 6) | v;
+    }
+  }
+  else {
+    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 overlay_resize(int force)
+{
+  int x2_mul = !in_menu && plat_target.vout_method > 1 ? 2 : 1; // lame
+  int w = in_menu ? g_menuscreen_w : psx_w;
+  int h = in_menu ? g_menuscreen_h : psx_h;
+
+  if (!force && plat_sdl_overlay && w * x2_mul == plat_sdl_overlay->w
+      && h == plat_sdl_overlay->h)
+    return;
+  if (plat_sdl_overlay)
+    SDL_FreeYUVOverlay(plat_sdl_overlay);
+  plat_sdl_overlay = SDL_CreateYUVOverlay(w * x2_mul, h, SDL_UYVY_OVERLAY,
+        plat_sdl_screen);
+  if (plat_sdl_overlay) {
+    //printf("overlay: %dx%d %08x hw=%d\n", plat_sdl_overlay->w, plat_sdl_overlay->h,
+    //    plat_sdl_overlay->format, plat_sdl_overlay->hw_overlay);
+    if (SDL_LockYUVOverlay(plat_sdl_overlay) == 0) {
+      plat_sdl_overlay_clear();
+      SDL_UnlockYUVOverlay(plat_sdl_overlay);
+    }
+  }
+  else
+    fprintf(stderr, "overlay resize to %dx%d failed\n", w, h);
+  handle_scaler_resize(w, h);
+}
+
+static void overlay_check_enable(void)
+{
+  // we no longer unconditionally call plat_sdl_change_video_mode()
+  // to not disturb the window, need to look for config change
+  if ((plat_target.vout_method == 0 || plat_sdl_gl_active) && plat_sdl_overlay) {
+    SDL_FreeYUVOverlay(plat_sdl_overlay);
+    plat_sdl_overlay = NULL;
   }
+  else if (plat_target.vout_method > 0 && !plat_sdl_gl_active) // lame
+    overlay_resize(0);
 }
 
 static void overlay_blit(int doffs, const void *src_, int w, int h,
@@ -210,6 +281,7 @@ static void overlay_blit(int doffs, const void *src_, int w, int h,
   const unsigned short *src = src_;
   unsigned short *dst;
   int dstride = plat_sdl_overlay->w;
+  int x2 = dstride >= 2 * w;
 
   SDL_LockYUVOverlay(plat_sdl_overlay);
   dst = (void *)plat_sdl_overlay->pixels[0];
@@ -217,11 +289,11 @@ static void overlay_blit(int doffs, const void *src_, int w, int h,
   dst += doffs;
   if (bgr24) {
     for (; h > 0; dst += dstride, src += sstride, h--)
-      bgr888_to_uyvy(dst, src, w);
+      bgr888_to_uyvy(dst, src, w, x2);
   }
   else {
     for (; h > 0; dst += dstride, src += sstride, h--)
-      bgr555_to_uyvy(dst, src, w);
+      bgr555_to_uyvy(dst, src, w, x2);
   }
 
   SDL_UnlockYUVOverlay(plat_sdl_overlay);
@@ -229,7 +301,11 @@ static void overlay_blit(int doffs, const void *src_, int w, int h,
 
 static void overlay_hud_print(int x, int y, const char *str, int bpp)
 {
+  int x2;
   SDL_LockYUVOverlay(plat_sdl_overlay);
+  x2 = plat_sdl_overlay->w >= psx_w * 2;
+  if (x2)
+    x *= 2;
   basic_text_out_uyvy_nf(plat_sdl_overlay->pixels[0], plat_sdl_overlay->w, x, y, str);
   SDL_UnlockYUVOverlay(plat_sdl_overlay);
 }
@@ -241,13 +317,39 @@ static void centered_clear(void)
   int h = plat_sdl_screen->h;
   unsigned short *dst;
 
-  SDL_LockSurface(plat_sdl_screen);
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_LockSurface(plat_sdl_screen);
   dst = plat_sdl_screen->pixels;
 
   for (; h > 0; dst += dstride, h--)
     memset(dst, 0, w * 2);
 
-  SDL_UnlockSurface(plat_sdl_screen);
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_UnlockSurface(plat_sdl_screen);
+
+  if (plat_sdl_overlay != NULL) {
+    // apply the parts not covered by the overlay
+    forced_flips = 3;
+  }
+}
+
+static int adj_src_dst(const SDL_Surface *sfc, int w, int pp, int *h,
+    unsigned short **dst, const unsigned short **src)
+{
+  int line_w = w;
+  if (sfc->w > w)
+    *dst += (sfc->w - w) / 2;
+  else {
+    *src += (w - sfc->w) / 2;
+    line_w = sfc->w;
+  }
+  if (sfc->h > *h)
+    *dst += sfc->pitch * (sfc->h - *h) / 2 / 2;
+  else {
+    *src += pp * (*h - sfc->h) / 2;
+    *h = sfc->h;
+  }
+  return line_w;
 }
 
 static void centered_blit(int doffs, const void *src_, int w, int h,
@@ -257,12 +359,12 @@ static void centered_blit(int doffs, const void *src_, int w, int h,
   unsigned short *dst;
   int dstride;
 
-  SDL_LockSurface(plat_sdl_screen);
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_LockSurface(plat_sdl_screen);
   dst = plat_sdl_screen->pixels;
   dstride = plat_sdl_screen->pitch / 2;
+  w = adj_src_dst(plat_sdl_screen, w, sstride, &h, &dst, &src);
 
-  dst += doffs + (plat_sdl_screen->w - w) / 2;
-  dst += dstride * (plat_sdl_screen->h - h) / 2;
   if (bgr24) {
     for (; h > 0; dst += dstride, src += sstride, h--)
       bgr888_to_rgb565(dst, src, w * 3);
@@ -272,7 +374,8 @@ static void centered_blit(int doffs, const void *src_, int w, int h,
       bgr555_to_rgb565(dst, src, w * 2);
   }
 
-  SDL_UnlockSurface(plat_sdl_screen);
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_UnlockSurface(plat_sdl_screen);
 }
 
 static void centered_blit_menu(void)
@@ -281,30 +384,39 @@ static void centered_blit_menu(void)
   int w = g_menuscreen_w;
   int h = g_menuscreen_h;
   unsigned short *dst;
-  int dstride;
+  int dstride, len;
+
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_LockSurface(plat_sdl_screen);
 
-  SDL_LockSurface(plat_sdl_screen);
   dst = plat_sdl_screen->pixels;
   dstride = plat_sdl_screen->pitch / 2;
+  len = adj_src_dst(plat_sdl_screen, w, g_menuscreen_pp, &h, &dst, &src);
 
-  dst += (plat_sdl_screen->w - w) / 2;
-  dst += dstride * (plat_sdl_screen->h - h) / 2;
   for (; h > 0; dst += dstride, src += g_menuscreen_pp, h--)
-    memcpy(dst, src, w * 2);
+    memcpy(dst, src, len * 2);
 
-  SDL_UnlockSurface(plat_sdl_screen);
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_UnlockSurface(plat_sdl_screen);
 }
 
 static void centered_hud_print(int x, int y, const char *str, int bpp)
 {
-  x += (plat_sdl_screen->w - psx_w) / 2;
-  y += (plat_sdl_screen->h - psx_h) / 2;
-  SDL_LockSurface(plat_sdl_screen);
+  int w_diff, h_diff;
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_LockSurface(plat_sdl_screen);
+  w_diff = plat_sdl_screen->w - psx_w;
+  h_diff = plat_sdl_screen->h - psx_h;
+  if (w_diff > 0) x += w_diff / 2;
+  if (h_diff > 0) y += h_diff / 2;
+  if (h_diff < 0) y += h_diff;
+  if (w_diff < 0 && x > 32) x += w_diff;
   basic_text_out16_nf(plat_sdl_screen->pixels, plat_sdl_screen->pitch / 2, x, y, str);
-  SDL_UnlockSurface(plat_sdl_screen);
+  if (SDL_MUSTLOCK(plat_sdl_screen))
+    SDL_UnlockSurface(plat_sdl_screen);
 }
 
-static void *setup_blit_callbacks(int w)
+static void *setup_blit_callbacks(int w, int h)
 {
   pl_plat_clear = NULL;
   pl_plat_blit = NULL;
@@ -318,43 +430,134 @@ static void *setup_blit_callbacks(int w)
     return shadow_fb;
   }
   else {
-    if (w == plat_sdl_screen->w)
+    pl_plat_clear = centered_clear;
+
+    if (!SDL_MUSTLOCK(plat_sdl_screen) && w == plat_sdl_screen->w &&
+        h == plat_sdl_screen->h)
       return plat_sdl_screen->pixels;
+
+    pl_plat_blit = centered_blit;
+    pl_plat_hud_print = centered_hud_print;
+  }
+  return NULL;
+}
+
+// not using plat_sdl_change_video_mode() since we need
+// different size overlay vs plat_sdl_screen layer
+static void change_mode(int w, int h)
+{
+  int set_w = w, set_h = h, had_overlay = 0;
+  if (plat_target.vout_fullscreen && (plat_target.vout_method != 0 || !sdl12_compat))
+    set_w = fs_w, set_h = fs_h;
+  if (plat_sdl_screen->w != set_w || plat_sdl_screen->h != set_h ||
+      plat_target.vout_fullscreen != vout_fullscreen_old)
+  {
+    Uint32 flags = plat_sdl_screen->flags;
+    if (plat_target.vout_fullscreen)
+      flags |= SDL_FULLSCREEN;
     else {
-      pl_plat_clear = centered_clear;
-      pl_plat_blit = centered_blit;
-      pl_plat_hud_print = centered_hud_print;
+      flags &= ~SDL_FULLSCREEN;
+      if (plat_sdl_is_windowed())
+        flags |= SDL_RESIZABLE; // sdl12-compat 1.2.68 loses this flag
+    }
+    if (plat_sdl_overlay) {
+      SDL_FreeYUVOverlay(plat_sdl_overlay);
+      plat_sdl_overlay = NULL;
+      had_overlay = 1;
     }
+    SDL_PumpEvents();
+    plat_sdl_screen = SDL_SetVideoMode(set_w, set_h, 16, flags);
+    //printf("mode: %dx%d %x -> %dx%d\n", set_w, set_h, flags,
+    //  plat_sdl_screen->w, plat_sdl_screen->h);
+    assert(plat_sdl_screen);
+    if (vout_fullscreen_old && !plat_target.vout_fullscreen)
+      // why is this needed?? (on 1.2.68)
+      SDL_WM_GrabInput(SDL_GRAB_OFF);
+    // overlay needs the latest plat_sdl_screen
+    if (had_overlay)
+      overlay_resize(1);
+    centered_clear();
+    vout_fullscreen_old = plat_target.vout_fullscreen;
+  }
+}
+
+static void handle_scaler_resize(int w, int h)
+{
+  int ww = plat_sdl_screen->w;
+  int wh = plat_sdl_screen->h;
+  int layer_w_old = g_layer_w;
+  int layer_h_old = g_layer_h;
+  pl_update_layer_size(w, h, ww, wh);
+  if (layer_w_old != g_layer_w || layer_h_old != g_layer_h)
+    forced_clears = 3;
+}
+
+static void handle_window_resize(void)
+{
+  // sdl12-compat: a hack to take advantage of sdl2 scaling
+  if (resized && (plat_target.vout_method != 0 || !sdl12_compat)) {
+    change_mode(window_w, window_h);
+    setup_blit_callbacks(psx_w, psx_h);
+    forced_clears = 3;
+    resized = 0;
   }
-  return NULL;
 }
 
 void *plat_gvideo_set_mode(int *w, int *h, int *bpp)
 {
   psx_w = *w;
   psx_h = *h;
-  change_video_mode(0);
-  if (plat_sdl_gl_active)
-    memset(shadow_fb, 0, psx_w * psx_h * 2);
-  return setup_blit_callbacks(*w);
+
+  if (plat_sdl_overlay != NULL)
+    overlay_resize(0);
+  else if (plat_sdl_gl_active)
+    memset(shadow_fb, 0, (*w) * (*h) * 2);
+  else if (plat_target.vout_method == 0) // && sdl12_compat
+    change_mode(*w, *h);
+
+  handle_scaler_resize(*w, *h); // override the value from pl_vout_set_mode()
+  return setup_blit_callbacks(*w, *h);
 }
 
 void *plat_gvideo_flip(void)
 {
+  void *ret = NULL;
+  int do_flip = 0;
   if (plat_sdl_overlay != NULL) {
-    SDL_Rect dstrect = { 0, 0, plat_sdl_screen->w, plat_sdl_screen->h };
+    SDL_Rect dstrect = {
+      (plat_sdl_screen->w - g_layer_w) / 2,
+      (plat_sdl_screen->h - g_layer_h) / 2,
+      g_layer_w, g_layer_h
+    };
+
     SDL_DisplayYUVOverlay(plat_sdl_overlay, &dstrect);
-    return NULL;
   }
   else if (plat_sdl_gl_active) {
     gl_flip(shadow_fb, psx_w, psx_h);
-    return shadow_fb;
+    ret = shadow_fb;
   }
-  else {
-    // XXX: no locking, but should be fine with SDL_SWSURFACE?
+  else
+    do_flip |= 2;
+
+  if (forced_flips > 0) {
+    forced_flips--;
+    do_flip |= 1;
+  }
+  if (do_flip)
     SDL_Flip(plat_sdl_screen);
-    return plat_sdl_screen->pixels;
+  handle_window_resize();
+  if (do_flip) {
+    if (forced_clears > 0) {
+      forced_clears--;
+      centered_clear();
+    }
+    if (!SDL_MUSTLOCK(plat_sdl_screen) && plat_sdl_screen->w == psx_w &&
+        plat_sdl_screen->h == psx_h && (do_flip & 2)) {
+      ret = plat_sdl_screen->pixels;
+    }
   }
+  assert(ret || pl_plat_clear != NULL);
+  return ret;
 }
 
 void plat_gvideo_close(void)
@@ -363,35 +566,65 @@ void plat_gvideo_close(void)
 
 void plat_video_menu_enter(int is_rom_loaded)
 {
-  int force_mode_change = 0;
-
   in_menu = 1;
 
   /* surface will be lost, must adjust pl_vout_buf for menu bg */
   if (plat_sdl_overlay != NULL)
-    uyvy_to_rgb565(menubg_img, plat_sdl_overlay->pixels[0], psx_w * psx_h);
+    uyvy_to_rgb565(menubg_img, psx_w * psx_h);
   else if (plat_sdl_gl_active)
     memcpy(menubg_img, shadow_fb, psx_w * psx_h * 2);
-  else
-    memcpy(menubg_img, plat_sdl_screen->pixels, psx_w * psx_h * 2);
+  else {
+    unsigned short *dst = menubg_img;
+    const unsigned short *src;
+    int h;
+    if (SDL_MUSTLOCK(plat_sdl_screen))
+      SDL_LockSurface(plat_sdl_screen);
+    src = plat_sdl_screen->pixels;
+    src += (plat_sdl_screen->w - psx_w) / 2;
+    src += plat_sdl_screen->pitch * (plat_sdl_screen->h - psx_h) / 2 / 2;
+    for (h = psx_h; h > 0; dst += psx_w, src += plat_sdl_screen->pitch / 2, h--)
+      memcpy(dst, src, psx_w * 2);
+    if (SDL_MUSTLOCK(plat_sdl_screen))
+      SDL_UnlockSurface(plat_sdl_screen);
+  }
   pl_vout_buf = menubg_img;
 
-  /* gles plugin messes stuff up.. */
-  if (pl_rearmed_cbs.gpu_caps & GPU_CAP_OWNS_DISPLAY)
-    force_mode_change = 1;
-
-  change_video_mode(force_mode_change);
+  if (plat_target.vout_method == 0)
+    change_mode(g_menuscreen_w, g_menuscreen_h);
+  else
+    overlay_check_enable();
+  centered_clear();
 }
 
 void plat_video_menu_begin(void)
 {
+  void *old_ovl = plat_sdl_overlay;
+  static int g_scaler_old;
+  int scaler_changed = g_scaler_old != g_scaler;
+  g_scaler_old = g_scaler;
+  if (plat_target.vout_fullscreen != vout_fullscreen_old ||
+      (plat_target.vout_fullscreen && scaler_changed)) {
+    change_mode(g_menuscreen_w, g_menuscreen_h);
+  }
+  else
+    overlay_check_enable();
+  handle_scaler_resize(g_menuscreen_w, g_menuscreen_h);
+
+  if (old_ovl != plat_sdl_overlay || scaler_changed)
+    centered_clear();
   g_menuscreen_ptr = shadow_fb;
 }
 
 void plat_video_menu_end(void)
 {
+  int do_flip = 0;
+
   if (plat_sdl_overlay != NULL) {
-    SDL_Rect dstrect = { 0, 0, plat_sdl_screen->w, plat_sdl_screen->h };
+    SDL_Rect dstrect = {
+      (plat_sdl_screen->w - g_layer_w) / 2,
+      (plat_sdl_screen->h - g_layer_h) / 2,
+      g_layer_w, g_layer_h
+    };
 
     SDL_LockYUVOverlay(plat_sdl_overlay);
     rgb565_to_uyvy(plat_sdl_overlay->pixels[0], shadow_fb,
@@ -405,21 +638,31 @@ void plat_video_menu_end(void)
   }
   else {
     centered_blit_menu();
-    SDL_Flip(plat_sdl_screen);
+    do_flip |= 2;
   }
+
+  if (forced_flips > 0) {
+    forced_flips--;
+    do_flip |= 1;
+  }
+  if (do_flip)
+    SDL_Flip(plat_sdl_screen);
+
+  handle_window_resize();
   g_menuscreen_ptr = NULL;
 }
 
 void plat_video_menu_leave(void)
 {
-  void *fb = NULL;
-  if (plat_sdl_overlay != NULL || plat_sdl_gl_active)
-    fb = shadow_fb;
-  else if (plat_sdl_screen)
-    fb = plat_sdl_screen->pixels;
-  if (fb)
-    memset(fb, 0, g_menuscreen_w * g_menuscreen_h * 2);
   in_menu = 0;
+  if (plat_sdl_overlay != NULL || plat_sdl_gl_active)
+    memset(shadow_fb, 0, g_menuscreen_w * g_menuscreen_h * 2);
+
+  if (plat_target.vout_fullscreen)
+    change_mode(fs_w, fs_h);
+  else
+    overlay_check_enable();
+  centered_clear();
 }
 
 /* unused stuff */
index 98e86ea..81998d5 100644 (file)
@@ -54,7 +54,7 @@ void *tsdev;
 void *pl_vout_buf;
 int g_layer_x, g_layer_y, g_layer_w, g_layer_h;
 static int pl_vout_w, pl_vout_h, pl_vout_bpp; /* output display/layer */
-static int pl_vout_scale_w, pl_vout_scale_h, pl_vout_yoffset;
+static int pl_vout_scale_w, pl_vout_scale_h;
 static int psx_w, psx_h, psx_bpp;
 static int vsync_cnt;
 static int is_pal, frame_interval, frame_interval1024;
@@ -178,7 +178,7 @@ static void print_hud(int x, int w, int h)
 }
 
 /* update scaler target size according to user settings */
-static void update_layer_size(int w, int h)
+void pl_update_layer_size(int w, int h, int fw, int fh)
 {
        float mult;
        int imult;
@@ -190,39 +190,45 @@ static void update_layer_size(int w, int h)
 
        case SCALE_2_2:
                g_layer_w = w; g_layer_h = h;
-               if (w * 2 <= g_menuscreen_w)
+               if (w * 2 <= fw)
                        g_layer_w = w * 2;
-               if (h * 2 <= g_menuscreen_h)
+               if (h * 2 <= fh)
                        g_layer_h = h * 2;
                break;
 
        case SCALE_4_3v2:
-               if (h > g_menuscreen_h || (240 < h && h <= 360))
-                       goto fractional_4_3;
+#ifdef PANDORA
+               if (h <= fh && !(240 < h && h <= 360))
+               {
+#endif
 
                // 4:3 that prefers integer scaling
-               imult = g_menuscreen_h / h;
+               imult = fh / h;
+               if (imult < 1)
+                       imult = 1;
                g_layer_w = w * imult;
                g_layer_h = h * imult;
                mult = (float)g_layer_w / (float)g_layer_h;
                if (mult < 1.25f || mult > 1.666f)
                        g_layer_w = 4.0f/3.0f * (float)g_layer_h;
-               printf("  -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult);
+               //printf("  -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult);
                break;
+#ifdef PANDORA
+               }
+#endif
 
-       fractional_4_3:
        case SCALE_4_3:
                mult = 240.0f / (float)h * 4.0f / 3.0f;
                if (h > 256)
                        mult *= 2.0f;
-               g_layer_w = mult * (float)g_menuscreen_h;
-               g_layer_h = g_menuscreen_h;
-               printf("  -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult);
+               g_layer_w = mult * (float)fh;
+               g_layer_h = fh;
+               //printf("  -> %dx%d %.1f\n", g_layer_w, g_layer_h, mult);
                break;
 
        case SCALE_FULLSCREEN:
-               g_layer_w = g_menuscreen_w;
-               g_layer_h = g_menuscreen_h;
+               g_layer_w = fw;
+               g_layer_h = fh;
                break;
 
        default:
@@ -230,11 +236,11 @@ static void update_layer_size(int w, int h)
        }
 
        if (g_scaler != SCALE_CUSTOM) {
-               g_layer_x = g_menuscreen_w / 2 - g_layer_w / 2;
-               g_layer_y = g_menuscreen_h / 2 - g_layer_h / 2;
+               g_layer_x = fw / 2 - g_layer_w / 2;
+               g_layer_y = fh / 2 - g_layer_h / 2;
        }
-       if (g_layer_w > g_menuscreen_w * 2) g_layer_w = g_menuscreen_w * 2;
-       if (g_layer_h > g_menuscreen_h * 2) g_layer_h = g_menuscreen_h * 2;
+       if (g_layer_w > fw * 2) g_layer_w = fw * 2;
+       if (g_layer_h > fh * 2) g_layer_h = fh * 2;
 }
 
 // XXX: this is platform specific really
@@ -246,7 +252,6 @@ static inline int resolution_ok(int w, int h)
 static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
 {
        int vout_w, vout_h, vout_bpp;
-       int buf_yoffset = 0;
 
        // special h handling, Wipeout likes to change it by 1-6
        static int vsync_cnt_ms_prev;
@@ -285,7 +290,7 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
        vout_w *= pl_vout_scale_w;
        vout_h *= pl_vout_scale_h;
 
-       update_layer_size(vout_w, vout_h);
+       pl_update_layer_size(vout_w, vout_h, g_menuscreen_w, g_menuscreen_h);
 
        pl_vout_buf = plat_gvideo_set_mode(&vout_w, &vout_h, &vout_bpp);
        if (pl_vout_buf == NULL && pl_plat_blit == NULL)
@@ -295,11 +300,7 @@ static void pl_vout_set_mode(int w, int h, int raw_w, int raw_h, int bpp)
                pl_vout_w = vout_w;
                pl_vout_h = vout_h;
                pl_vout_bpp = vout_bpp;
-               pl_vout_yoffset = buf_yoffset;
        }
-       if (pl_vout_buf != NULL)
-               pl_vout_buf = (char *)pl_vout_buf
-                       + pl_vout_yoffset * pl_vout_w * pl_vout_bpp / 8;
 
        menu_notify_mode_change(pl_vout_w, pl_vout_h, pl_vout_bpp);
 }
@@ -317,7 +318,7 @@ static void pl_vout_flip(const void *vram_, int vram_ofs, int bgr24,
        unsigned char *dest = pl_vout_buf;
        const unsigned char *vram = vram_;
        int dstride = pl_vout_w, h1 = h;
-       int h_full = pl_vout_h - pl_vout_yoffset;
+       int h_full = pl_vout_h;
        int enhres = w > psx_w;
        int xoffs = 0, doffs;
        int hwrapped;
@@ -465,9 +466,6 @@ out:
 
        // let's flip now
        pl_vout_buf = plat_gvideo_flip();
-       if (pl_vout_buf != NULL)
-               pl_vout_buf = (char *)pl_vout_buf
-                       + pl_vout_yoffset * pl_vout_w * pl_vout_bpp / 8;
 
        pl_rearmed_cbs.flip_cnt++;
 }
index 855c716..74a7372 100644 (file)
@@ -48,6 +48,7 @@ void  pl_force_clear(void);
 
 void  pl_timing_prepare(int is_pal);
 void  pl_frame_limit(void);
+void  pl_update_layer_size(int w, int h, int fw, int fh);
 
 // for communication with gpulib
 struct rearmed_cbs {