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;
- }
- // 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 < 65536; i++) {
- int r = (i >> 11) & 0x1f, g = (i >> 6) & 0x1f, b = (i >> 0) & 0x1f;
- int y = (yuv_ry[r] + yuv_gy[g] + yuv_by[b]) >> 16;
- yuv_uyvy[i].y = yuv_y[y];
+ 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 < 65536; i++) {
+ int r = (i >> 11) & 0x1f, g = (i >> 6) & 0x1f, b = (i >> 0) & 0x1f;
+ int y = (yuv_ry[r] + yuv_gy[g] + yuv_by[b]) >> 16;
+ yuv_uyvy[i].y = yuv_y[y];
#if CPU_IS_LE
- yuv_uyvy[i].vyu = (yuv_v[r-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[b-y + 32];
+ yuv_uyvy[i].vyu = (yuv_v[r-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[b-y + 32];
#else
- yuv_uyvy[i].vyu = (yuv_v[b-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[r-y + 32];
+ yuv_uyvy[i].vyu = (yuv_v[b-y + 32] << 16) | (yuv_y[y] << 8) | yuv_u[r-y + 32];
#endif
- }
+ }
}
void rgb565_to_uyvy(void *d, const void *s, int w, int h, int pitch, int dpitch, int x2)
{
- uint32_t *dst = d;
- const uint16_t *src = s;
- int i;
-
- if (x2) while (h--) {
- for (i = w; i >= 4; src += 4, dst += 4, i -= 4)
- {
- struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
- struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
+ uint32_t *dst = d;
+ const uint16_t *src = s;
+ int i;
+
+ if (x2) while (h--) {
+ for (i = w; i >= 4; src += 4, dst += 4, i -= 4)
+ {
+ struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
+ struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
#if CPU_IS_LE
- 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;
+ 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;
#else
- 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);
+ 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);
#endif
- }
- src += pitch - (w-i);
- dst += (dpitch - 2*(w-i))/2;
- } else while (h--) {
- for (i = w; i >= 4; src += 4, dst += 2, i -= 4)
- {
- struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
- struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
+ }
+ src += pitch - (w-i);
+ dst += (dpitch - 2*(w-i))/2;
+ } else while (h--) {
+ for (i = w; i >= 4; src += 4, dst += 2, i -= 4)
+ {
+ struct uyvy *uyvy0 = yuv_uyvy + src[0], *uyvy1 = yuv_uyvy + src[1];
+ struct uyvy *uyvy2 = yuv_uyvy + src[2], *uyvy3 = yuv_uyvy + src[3];
#if CPU_IS_LE
- dst[0] = (uyvy1->y << 24) | uyvy0->vyu;
- dst[1] = (uyvy3->y << 24) | uyvy2->vyu;
+ dst[0] = (uyvy1->y << 24) | uyvy0->vyu;
+ dst[1] = (uyvy3->y << 24) | uyvy2->vyu;
#else
- dst[0] = uyvy1->y | (uyvy0->vyu << 8);
- dst[1] = uyvy3->y | (uyvy2->vyu << 8);
+ dst[0] = uyvy1->y | (uyvy0->vyu << 8);
+ dst[1] = uyvy3->y | (uyvy2->vyu << 8);
#endif
- }
- src += pitch - (w-i);
- dst += (dpitch - (w-i))/2;
- }
+ }
+ src += pitch - (w-i);
+ dst += (dpitch - (w-i))/2;
+ }
}
void copy_intscale(void *dst, int w, int h, int pp, void *src, int sw, int sh, int spp)
void plat_video_set_size(int w, int h)
{
if ((plat_sdl_overlay || plat_sdl_gl_active) &&
- (w != g_screen_width || h != g_screen_height)) {
+ (w != g_screen_width || h != g_screen_height)) {
// scale to the window, but mind aspect ratio (scaled to 4:3)
- if (g_menuscreen_w * /*h*/w*3/4 >= g_menuscreen_h * w)
+ if (g_menuscreen_w * 3/4 >= g_menuscreen_h)
w = (w * 3 * g_menuscreen_w/g_menuscreen_h)/4 & ~1;
else
h = (h * 4 * g_menuscreen_h/g_menuscreen_w)/3 & ~1;
}
}
if (plat_sdl_overlay || plat_sdl_gl_active ||
- plat_sdl_screen->w >= 320*2 || plat_sdl_screen->h >= 240*2) {
+ (plat_sdl_screen->w >= 320*2 || plat_sdl_screen->h >= 240*2 ||
+ plat_sdl_screen->w < 320 || plat_sdl_screen->h < 240)) {
// use shadow buffer for overlays and sw integer scaling
g_screen_width = area.w;
g_screen_height = area.h;
if (SDL_MUSTLOCK(plat_sdl_screen))
SDL_UnlockSurface(plat_sdl_screen);
SDL_Flip(plat_sdl_screen);
- if (SDL_MUSTLOCK(plat_sdl_screen))
- SDL_LockSurface(plat_sdl_screen);
- if (!copy) {
+ // take over resized settings for the physical SDL surface
+ if ((plat_sdl_screen->w != g_menuscreen_w ||
+ plat_sdl_screen->h != g_menuscreen_h) && plat_sdl_is_windowed() &&
+ SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) {
+ plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, 1);
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ g_menuscreen_pp = plat_sdl_screen->pitch/2;
+
+ // force upper layer to use new dimensions
+ plat_video_set_shadow(g_screen_width, g_screen_height);
+ plat_video_set_buffer(g_screen_ptr);
+ rendstatus_old = -1;
+ } else if (!copy) {
g_screen_ppitch = plat_sdl_screen->pitch/2;
g_screen_ptr = plat_sdl_screen->pixels;
plat_video_set_buffer(g_screen_ptr);
}
+ if (SDL_MUSTLOCK(plat_sdl_screen))
+ SDL_LockSurface(plat_sdl_screen);
+
if (clear_buf_cnt) {
memset(g_screen_ptr, 0, plat_sdl_screen->pitch*plat_sdl_screen->h);
clear_buf_cnt--;
{
if (plat_sdl_overlay || plat_sdl_gl_active ||
plat_sdl_screen->w >= 320*2 || plat_sdl_screen->h >= 240*2)
- memset(shadow_fb, 0, g_menuscreen_pp * g_menuscreen_h * 2);
+ memset(shadow_fb, 0, g_menuscreen_w * g_menuscreen_h * 2);
else {
memset(g_screen_ptr, 0, plat_sdl_screen->pitch*plat_sdl_screen->h);
clear_buf_cnt = 3; // do it thrice in case of triple buffering
void plat_video_menu_update(void)
{
- // w/h might have changed due to resizing
- plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, 1);
- resize_buffers();
+ // WM may grab input while resizing the window; our own window resizing
+ // is only safe if the WM isn't active anymore, so try to grab input.
+ if (plat_sdl_is_windowed() && SDL_WM_GrabInput(SDL_GRAB_ON) == SDL_GRAB_ON) {
+ // w/h might change in resize callback
+ int w, h;
+ do {
+ w = g_menuscreen_w, h = g_menuscreen_h;
+ plat_sdl_change_video_mode(w, h, 1);
+ } while (w != g_menuscreen_w || h != g_menuscreen_h);
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ }
// update pitch as it is needed by the menu bg scaler
if (plat_sdl_overlay || plat_sdl_gl_active)
void plat_video_loop_prepare(void)
{
// take over any new vout settings
+ area = (struct area) { 0, 0 };
plat_sdl_change_video_mode(0, 0, 0);
- area.w = g_menuscreen_w, area.h = g_menuscreen_h;
resize_buffers();
// switch over to scaled output if available, but keep the aspect ratio
g_screen_ptr = shadow_fb;
}
else {
+ plat_video_set_size(g_menuscreen_w, g_menuscreen_h);
if (plat_sdl_is_windowed() &&
- (plat_sdl_screen->w >= 320*2 || plat_sdl_screen->h >= 240*2)) {
+ (plat_sdl_screen->w >= 320*2 || plat_sdl_screen->h >= 240*2 ||
+ plat_sdl_screen->w < 320 || plat_sdl_screen->h < 240)) {
// shadow buffer for integer scaling
g_screen_width = 320;
g_screen_height = 240;
g_screen_ppitch = plat_sdl_screen->pitch/2;
g_screen_ptr = plat_sdl_screen->pixels;
}
- plat_video_set_size(g_screen_width, g_screen_height);
if (SDL_MUSTLOCK(plat_sdl_screen))
SDL_LockSurface(plat_sdl_screen);
{
g_menuscreen_h = plat_sdl_screen->h;
g_menuscreen_w = plat_sdl_screen->w;
+
+ if (!plat_sdl_overlay && !plat_sdl_gl_active &&
+ plat_sdl_is_windowed() && !plat_sdl_is_fullscreen()) {
+ // in SDL window mode, adapt window to integer scaling
+ if (g_menuscreen_w * 3/4 >= g_menuscreen_h)
+ g_menuscreen_w = g_menuscreen_h * 4/3;
+ else
+ g_menuscreen_h = g_menuscreen_w * 3/4;
+ g_menuscreen_w = g_menuscreen_w/320*320;
+ g_menuscreen_h = g_menuscreen_h/240*240;
+ if (g_menuscreen_w == 0) {
+ g_menuscreen_w = 320;
+ g_menuscreen_h = 240;
+ }
+ }
}
+
resize_buffers();
rendstatus_old = -1;
}
ret = plat_sdl_init();
if (ret != 0)
exit(1);
+
#if defined(__OPENDINGUX__)
// opendingux on JZ47x0 may falsely report a HW overlay, fix to window
plat_target.vout_method = 0;
+#elif !defined(__MIYOO__) && !defined(__RETROFW__) && !defined(__DINGUX__)
+ if (! plat_sdl_is_windowed())
#endif
+ SDL_ShowCursor(0);
plat_sdl_quit_cb = plat_sdl_quit;
plat_sdl_resize_cb = plat_sdl_resize;
- SDL_ShowCursor(0);
SDL_WM_SetCaption("PicoDrive " VERSION, NULL);
g_menuscreen_pp = g_menuscreen_w;