Browse Source

sdl, fix scaling for non-4:3 display

root 2 years ago
parent
commit
9c60f28aa1
3 changed files with 39 additions and 39 deletions
  1. 10 7
      pico/mode4.c
  2. 2 2
      platform/common/plat_sdl.c
  3. 27 30
      platform/linux/emu.c

+ 10 - 7
pico/mode4.c

@@ -14,6 +14,7 @@
  * - doubled sprites
  */
 #include "pico_int.h"
+#include <platform/common/upscale.h>
 
 static void (*FinalizeLineM4)(int line);
 static int skip_next_line;
@@ -272,9 +273,10 @@ static void DrawDisplayM4(int scanline)
   }
 }
 
+static void FinalizeLineRGB555M4(int line);
 void PicoFrameStartMode4(void)
 {
-  int lines = 192;
+  int lines = 192, coffs;
   skip_next_line = 0;
   screen_offset = 24;
   Pico.est.rendstatus = PDRAW_32_COLS;
@@ -289,9 +291,13 @@ void PicoFrameStartMode4(void)
       lines = 224;
     }
   }
+  line_offset = PicoIn.opt & (POPT_DIS_32C_BORDER|POPT_EN_SOFTSCALE) ? 0 : 32;
+  coffs = line_offset;
+  if (FinalizeLineM4 == FinalizeLineRGB555M4)
+    line_offset = 0 /* done in FinalizeLine */;
 
   if (Pico.est.rendstatus != rendstatus_old || lines != rendlines) {
-    emu_video_mode_change(screen_offset, lines, line_offset, 256);
+    emu_video_mode_change(screen_offset, lines, coffs, 256);
     rendstatus_old = Pico.est.rendstatus;
     rendlines = lines;
   }
@@ -352,8 +358,6 @@ void PicoDoHighPal555M4(void)
   Pico.est.HighPal[0xe0] = 0;
 }
 
-#include <platform/common/upscale.h>
-
 static void FinalizeLineRGB555M4(int line)
 {
   if (Pico.m.dirtyPal)
@@ -379,15 +383,14 @@ static void FinalizeLine8bitM4(int line)
 
 void PicoDrawSetOutputMode4(pdso_t which)
 {
-  line_offset = PicoIn.opt & (POPT_DIS_32C_BORDER|POPT_EN_SOFTSCALE) ? 0 : 32;
   switch (which)
   {
     case PDF_8BIT:   FinalizeLineM4 = FinalizeLine8bitM4; break;
-    case PDF_RGB555: FinalizeLineM4 = FinalizeLineRGB555M4;
-                     line_offset = 0 /* done in FinalizeLine */; break;
+    case PDF_RGB555: FinalizeLineM4 = FinalizeLineRGB555M4; break;
     default:         FinalizeLineM4 = NULL;
                      PicoDrawSetInternalBuf(Pico.est.Draw2FB, 328); break;
   }
+  rendstatus_old = -1;
 }
 
 // vim:shiftwidth=2:ts=2:expandtab

+ 2 - 2
platform/common/plat_sdl.c

@@ -1749,9 +1749,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);

+ 27 - 30
platform/linux/emu.c

@@ -97,12 +97,8 @@ static void draw_cd_leds(void)
 
 static u16 *screen_buffer(u16 *buf)
 {
-	// center the emulator display on the screen if screen is larger
-	if (currentConfig.scaling != EOPT_SCALE_HW)
-		buf += (g_screen_width-320)/2;
-	if (currentConfig.vscaling != EOPT_SCALE_HW)
-		buf += (g_screen_height-240)/2 * g_screen_ppitch;
-	return buf;
+	return buf + screen_y * g_screen_ppitch + screen_x -
+			(out_y * g_screen_ppitch + out_x);
 }
 
 void screen_blit(u16 *pd, int pp, u8* ps, int ss, u16 *pal)
@@ -151,8 +147,8 @@ void pemu_finalize_frame(const char *fps, const char *notice)
 	if (!is_16bit_mode()) {
 		// convert the 8 bit CLUT output to 16 bit RGB
 		u16 *pd = screen_buffer(g_screen_ptr) +
-					screen_y * g_screen_ppitch + screen_x;
-		u8  *ps = Pico.est.Draw2FB + 328*out_y + out_x + 8;
+				out_y * g_screen_ppitch + out_x;
+		u8  *ps = Pico.est.Draw2FB + out_y * 328 + out_x + 8;
 
 		PicoDrawUpdateHighPal();
 
@@ -181,6 +177,7 @@ void plat_video_set_buffer(void *buf)
 static void apply_renderer(void)
 {
 	PicoIn.opt &= ~(POPT_ALT_RENDERER|POPT_EN_SOFTSCALE|POPT_DIS_32C_BORDER);
+
 	switch (get_renderer()) {
 	case RT_16BIT:
 		// 32X uses line mode for vscaling with accurate renderer, since
@@ -204,7 +201,7 @@ static void apply_renderer(void)
 
 	if (PicoIn.AHW & PAHW_32X)
 		PicoDrawSetOutBuf(screen_buffer(g_screen_ptr), g_screen_ppitch * 2);
-	else if (is_16bit_mode()) {
+	if (is_16bit_mode()) {
 		if (currentConfig.scaling == EOPT_SCALE_SW) {
 			PicoIn.opt |= POPT_EN_SOFTSCALE;
 			PicoIn.filter = currentConfig.filter;
@@ -266,7 +263,6 @@ void plat_debug_cat(char *str)
 
 void pemu_forced_frame(int no_scale, int do_emu)
 {
-	u16 *pd = screen_buffer(g_screen_ptr);
 	int hs = currentConfig.scaling, vs = currentConfig.vscaling;
 
 	// create centered and sw scaled (if scaling enabled) 16 bit output
@@ -274,11 +270,11 @@ void pemu_forced_frame(int no_scale, int do_emu)
 	Pico.m.dirtyPal = 1;
 	if (currentConfig.scaling)  currentConfig.scaling  = EOPT_SCALE_SW;
 	if (currentConfig.vscaling) currentConfig.vscaling = EOPT_SCALE_SW;
-	plat_video_set_size(320, 240);
+	plat_video_set_size(g_menuscreen_w, g_menuscreen_h);
 
 	// render a frame in 16 bit mode
 	render_bg = 1;
-	emu_cmn_forced_frame(no_scale, do_emu, pd);
+	emu_cmn_forced_frame(no_scale, do_emu, screen_buffer(g_screen_ptr));
 	render_bg = 0;
 
 	g_menubg_src_ptr = g_screen_ptr;
@@ -295,8 +291,8 @@ static int cb_vscaling_begin(unsigned int line)
 	// at start of new frame?
 	if (line < prevline) {
 		// set y frame offset (see emu_change_video_mode)
-		u16 *dest = g_screen_ptr;
-		Pico.est.DrawLineDest = dest + screen_y * g_screen_ppitch;
+		Pico.est.DrawLineDest = screen_buffer(g_screen_ptr) +
+				(out_y * g_screen_ppitch + out_x);
 		vscale_state = 0;
 	}
 	prevline = line;
@@ -332,42 +328,43 @@ void emu_video_mode_change(int start_line, int line_count, int start_col, int co
 	out_h = line_count; out_w = col_count;
 
 	PicoDrawSetCallbacks(NULL, NULL);
-	screen_x = screen_y = 0;
-	screen_w = 320, screen_h = 240;
+	// center output in screen
+	screen_w = g_screen_width,  screen_x = (screen_w - out_w)/2;
+	screen_h = g_screen_height, screen_y = (screen_h - out_h)/2;
 
 	switch (currentConfig.scaling) {
 	case EOPT_SCALE_HW:
 		screen_w = out_w;
+		screen_x = 0;
 		break;
-	case EOPT_SCALE_NONE:
-		// center output in screen
-		screen_x = (screen_w - out_w)/2;
+	case EOPT_SCALE_SW:
+		screen_x = (screen_w - 320)/2;
 		break;
 	}
 	switch (currentConfig.vscaling) {
 	case EOPT_SCALE_HW:
-		// NTSC always has 224 visible lines, anything smaller has bars
 		screen_h = (out_h < 224 ? 224 : out_h);
+		screen_y = 0;
+		// NTSC always has 224 visible lines, anything smaller has bars
+		if (out_h < 224)
+			screen_y += (224 - out_h)/2;
 		// handle vertical centering for 16 bit mode
-		screen_y = (screen_h - out_h) / 2;
 		if (is_16bit_mode())
-			PicoDrawSetCallbacks(cb_vscaling_begin, cb_vscaling_nop);
+			PicoDrawSetCallbacks(cb_vscaling_begin,cb_vscaling_nop);
 		break;
 	case EOPT_SCALE_SW:
+		screen_y = (screen_h - 240)/2;
 		// NTSC always has 224 visible lines, anything smaller has bars
-		if (out_y > 7)
-			screen_y = out_y - 7;
+		if (out_h < 224)
+			screen_y += (224 - out_h)/2;
 		// in 16 bit mode sw scaling is divided between core and platform
 		if (is_16bit_mode() && out_h < 240)
-			PicoDrawSetCallbacks(cb_vscaling_begin, cb_vscaling_end);
-		break;
-	case EOPT_SCALE_NONE:
-		// center output in screen
-		screen_y = (screen_h - out_h)/2;
+			PicoDrawSetCallbacks(cb_vscaling_begin,cb_vscaling_end);
 		break;
 	}
 
-	plat_video_set_size(screen_w, screen_h);
+	if (screen_w != g_screen_width || screen_h != g_screen_height)
+		plat_video_set_size(screen_w, screen_h);
 	plat_video_set_buffer(g_screen_ptr);
 
 	// clear whole screen in all buffers