sdl, fix scaling for non-4:3 display
authorkub <derkub@gmail.com>
Sat, 11 Sep 2021 20:18:38 +0000 (22:18 +0200)
committerkub <derkub@gmail.com>
Sat, 11 Sep 2021 20:18:38 +0000 (22:18 +0200)
platform/common/plat_sdl.c
platform/linux/emu.c

index f8bf78c..7198136 100644 (file)
@@ -253,9 +253,9 @@ void plat_video_loop_prepare(void)
 {
        // take over any new vout settings
        plat_sdl_change_video_mode(g_menuscreen_w, g_menuscreen_h, 0);
-       // switch over to scaled output if available
+       // switch over to scaled output if available, but keep the aspect ratio
        if (plat_sdl_overlay != NULL || plat_sdl_gl_active) {
-               g_screen_width = 320;
+               g_screen_width = (240 * g_menuscreen_w / g_menuscreen_h) & ~1;
                g_screen_height = 240;
                g_screen_ppitch = g_screen_width;
                plat_sdl_change_video_mode(g_screen_width, g_screen_height, 0);
index 0b0c53d..5cfea5d 100644 (file)
@@ -97,12 +97,8 @@ static void draw_cd_leds(void)
 \r
 static u16 *screen_buffer(u16 *buf)\r
 {\r
-       // center the emulator display on the screen if screen is larger\r
-       if (currentConfig.scaling != EOPT_SCALE_HW)\r
-               buf += (g_screen_width-320)/2;\r
-       if (currentConfig.vscaling != EOPT_SCALE_HW)\r
-               buf += (g_screen_height-240)/2 * g_screen_ppitch;\r
-       return buf;\r
+       return buf + screen_y * g_screen_ppitch + screen_x -\r
+                       (out_y * g_screen_ppitch + out_x);\r
 }\r
 \r
 void screen_blit(u16 *pd, int pp, u8* ps, int ss, u16 *pal)\r
@@ -151,8 +147,8 @@ void pemu_finalize_frame(const char *fps, const char *notice)
        if (!is_16bit_mode()) {\r
                // convert the 8 bit CLUT output to 16 bit RGB\r
                u16 *pd = screen_buffer(g_screen_ptr) +\r
-                                       screen_y * g_screen_ppitch + screen_x;\r
-               u8  *ps = Pico.est.Draw2FB + 328*out_y + out_x + 8;\r
+                               out_y * g_screen_ppitch + out_x;\r
+               u8  *ps = Pico.est.Draw2FB + out_y * 328 + out_x + 8;\r
 \r
                PicoDrawUpdateHighPal();\r
 \r
@@ -260,7 +256,6 @@ void plat_debug_cat(char *str)
 \r
 void pemu_forced_frame(int no_scale, int do_emu)\r
 {\r
-       u16 *pd = screen_buffer(g_screen_ptr);\r
        int hs = currentConfig.scaling, vs = currentConfig.vscaling;\r
 \r
        // create centered and sw scaled (if scaling enabled) 16 bit output\r
@@ -268,11 +263,11 @@ void pemu_forced_frame(int no_scale, int do_emu)
        Pico.m.dirtyPal = 1;\r
        if (currentConfig.scaling)  currentConfig.scaling  = EOPT_SCALE_SW;\r
        if (currentConfig.vscaling) currentConfig.vscaling = EOPT_SCALE_SW;\r
-       plat_video_set_size(320, 240);\r
+       plat_video_set_size(g_menuscreen_w, g_menuscreen_h);\r
 \r
        // render a frame in 16 bit mode\r
        render_bg = 1;\r
-       emu_cmn_forced_frame(no_scale, do_emu, pd);\r
+       emu_cmn_forced_frame(no_scale, do_emu, screen_buffer(g_screen_ptr));\r
        render_bg = 0;\r
 \r
        g_menubg_src_ptr = g_screen_ptr;\r
@@ -289,8 +284,8 @@ static int cb_vscaling_begin(unsigned int line)
        // at start of new frame?\r
        if (line < prevline) {\r
                // set y frame offset (see emu_change_video_mode)\r
-               u16 *dest = g_screen_ptr;\r
-               Pico.est.DrawLineDest = dest + screen_y * g_screen_ppitch;\r
+               Pico.est.DrawLineDest = screen_buffer(g_screen_ptr) +\r
+                               (out_y * g_screen_ppitch + out_x);\r
                vscale_state = 0;\r
        }\r
        prevline = line;\r
@@ -326,42 +321,44 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
        out_h = line_count; out_w = col_count;\r
 \r
        PicoDrawSetCallbacks(NULL, NULL);\r
-       screen_x = screen_y = 0;\r
-       screen_w = 320, screen_h = 240;\r
+       // center output in screen\r
+       screen_w = g_screen_width,  screen_x = (screen_w - out_w)/2;\r
+       screen_h = g_screen_height, screen_y = (screen_h - out_h)/2;\r
+\r
 \r
        switch (currentConfig.scaling) {\r
        case EOPT_SCALE_HW:\r
                screen_w = out_w;\r
+               screen_x = 0;\r
                break;\r
-       case EOPT_SCALE_NONE:\r
-               // center output in screen\r
-               screen_x = (screen_w - out_w)/2;\r
+       case EOPT_SCALE_SW:\r
+               screen_x = (screen_w - 320)/2;\r
                break;\r
        }\r
        switch (currentConfig.vscaling) {\r
        case EOPT_SCALE_HW:\r
-               // NTSC always has 224 visible lines, anything smaller has bars\r
                screen_h = (out_h < 224 ? 224 : out_h);\r
+               screen_y = 0;\r
+               // NTSC always has 224 visible lines, anything smaller has bars\r
+               if (out_h < 224)\r
+                       screen_y += (224 - out_h)/2;\r
                // handle vertical centering for 16 bit mode\r
-               screen_y = (screen_h - out_h) / 2;\r
                if (is_16bit_mode())\r
-                       PicoDrawSetCallbacks(cb_vscaling_begin, cb_vscaling_nop);\r
+                       PicoDrawSetCallbacks(cb_vscaling_begin,cb_vscaling_nop);\r
                break;\r
        case EOPT_SCALE_SW:\r
+               screen_y = (screen_h - 240)/2;\r
                // NTSC always has 224 visible lines, anything smaller has bars\r
-               if (out_y > 7)\r
-                       screen_y = out_y - 7;\r
+               if (out_h < 224)\r
+                       screen_y += (224 - out_h)/2;\r
                // in 16 bit mode sw scaling is divided between core and platform\r
                if (is_16bit_mode() && out_h < 240)\r
-                       PicoDrawSetCallbacks(cb_vscaling_begin, cb_vscaling_end);\r
-               break;\r
-       case EOPT_SCALE_NONE:\r
-               // center output in screen\r
-               screen_y = (screen_h - out_h)/2;\r
+                       PicoDrawSetCallbacks(cb_vscaling_begin,cb_vscaling_end);\r
                break;\r
        }\r
 \r
-       plat_video_set_size(screen_w, screen_h);\r
+       if (screen_w != g_screen_width || screen_h != g_screen_height)\r
+               plat_video_set_size(screen_w, screen_h);\r
        plat_video_set_buffer(g_screen_ptr);\r
 \r
        // clear whole screen in all buffers\r