+static void uyvy_to_rgb565(void *d, const void *s, int 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 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 = plat_sdl_overlay->w;
+
+ SDL_LockYUVOverlay(plat_sdl_overlay);
+ dst = (void *)plat_sdl_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(plat_sdl_overlay);
+}
+
+static void overlay_hud_print(int x, int y, const char *str, int bpp)
+{
+ SDL_LockYUVOverlay(plat_sdl_overlay);
+ basic_text_out_uyvy_nf(plat_sdl_overlay->pixels[0], plat_sdl_overlay->w, x, y, str);
+ SDL_UnlockYUVOverlay(plat_sdl_overlay);
+}
+
+static void centered_clear(void)
+{
+ int dstride = plat_sdl_screen->pitch / 2;
+ int w = plat_sdl_screen->w;
+ int h = plat_sdl_screen->h;
+ unsigned short *dst;
+
+ 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);
+}
+
+static void centered_blit(int doffs, const void *src_, int w, int h,
+ int sstride, int bgr24)
+{
+ const unsigned short *src = src_;
+ unsigned short *dst;
+ int dstride;
+
+ SDL_LockSurface(plat_sdl_screen);
+ dst = plat_sdl_screen->pixels;
+ dstride = plat_sdl_screen->pitch / 2;
+
+ 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);
+ }
+ else {
+ for (; h > 0; dst += dstride, src += sstride, h--)
+ bgr555_to_rgb565(dst, src, w * 2);
+ }
+
+ SDL_UnlockSurface(plat_sdl_screen);
+}
+
+static void centered_blit_menu(void)
+{
+ const unsigned short *src = g_menuscreen_ptr;
+ int w = g_menuscreen_w;
+ int h = g_menuscreen_h;
+ unsigned short *dst;
+ int dstride;
+
+ SDL_LockSurface(plat_sdl_screen);
+ dst = plat_sdl_screen->pixels;
+ dstride = plat_sdl_screen->pitch / 2;
+
+ 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);
+
+ 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);
+ basic_text_out16_nf(plat_sdl_screen->pixels, plat_sdl_screen->pitch / 2, x, y, str);
+ SDL_UnlockSurface(plat_sdl_screen);
+}
+
+static void *setup_blit_callbacks(int w)
+{
+ pl_plat_clear = NULL;
+ pl_plat_blit = NULL;
+ pl_plat_hud_print = NULL;
+ if (plat_sdl_overlay != NULL) {
+ pl_plat_clear = plat_sdl_overlay_clear;
+ pl_plat_blit = overlay_blit;
+ pl_plat_hud_print = overlay_hud_print;
+ }
+ else if (plat_sdl_gl_active) {
+ return shadow_fb;
+ }
+ else {
+ if (w == plat_sdl_screen->w)
+ return plat_sdl_screen->pixels;
+ else {
+ pl_plat_clear = centered_clear;
+ pl_plat_blit = centered_blit;
+ pl_plat_hud_print = centered_hud_print;
+ }
+ }
+ return NULL;
+}
+