retro-go icon indicating copy to clipboard operation
retro-go copied to clipboard

Feature Request: Downscaling for Small Screens

Open Cralex opened this issue 3 years ago • 1 comments
trafficstars

As mentioned in another issue, Retro-Go doesn't scale down gameplay on devices with small screens. On my WIP Game Box Mini port, games from all non-handheld systems always look great horizontally, but are cropped vertically. While Retro-Go's implementation of NES emulation, for example, is unspeakably good compared to the stock firmware's, there are a few games that can't be played properly on Retro-Go. Here's the NES release of Montezuma's Revenge, first on stock then on Retro-Go. image image

Would downscaling be worth considering sometime in the future, especially as Retro-Go is ported to the GBM and other tiny systems? I don't know if it would be difficult to implement without knowing the screen size beforehand or not... Thanks for the consideration. :)

Cralex avatar Nov 10 '22 02:11 Cralex

Simple downscaling is easy, the harder part is making sure the rest of the code is aware of it (all the cropping and scaling calculations and filtering in particular).

Here's a starting point for vertical downscaling that I would not accept as patch, but it works if you want to mess around!

diff --git a/components/retro-go/rg_display.c b/components/retro-go/rg_display.c
index ba2c416e..8932bee5 100644
--- a/components/retro-go/rg_display.c
+++ b/components/retro-go/rg_display.c
@@ -436,6 +436,9 @@ static inline void write_rect(int left, int top, int width, int height,
         scaled_height
     );

+    height = display.source.height + display.source.crop_v * 2;
+    int skip_lines = height > screen_height ? (height / (height - screen_height)) : 0;
+
     for (int y = 0, screen_y = screen_top; y < height;)
     {
         int lines_to_copy = RG_MIN(lines_per_buffer, screen_bottom - screen_y);
@@ -488,6 +491,12 @@ static inline void write_rect(int left, int top, int width, int height,
                 buffer.u8 += stride;
                 ++y;
             }
+
+            if (skip_lines > 0 && (y % skip_lines) == 0)
+            {
+                buffer.u8 += stride;
+                ++y;
+            }
         }

         if (filter_y || filter_x)
@@ -948,7 +957,7 @@ void rg_display_set_source_format(int width, int height, int crop_h, int crop_v,
     display.source.format = format;
     display.source.stride = stride;
     display.source.pixlen = format & RG_PIXEL_PAL ? 1 : 2;
-    display.source.offset = (display.source.crop_v * stride) + (display.source.crop_h * display.source.pixlen);
+    display.source.offset = (display.source.crop_h * display.source.pixlen);
     display.changed = true;
 }

@@ -1061,9 +1070,9 @@ void rg_display_init(void)
     config = (rg_display_config_t){
         .backlight = rg_settings_get_number(NS_GLOBAL, SETTING_BACKLIGHT, 80),
         .scaling = rg_settings_get_number(NS_APP, SETTING_SCALING, RG_DISPLAY_SCALING_FILL),
-        .filter = rg_settings_get_number(NS_APP, SETTING_FILTER, RG_DISPLAY_FILTER_BOTH),
+        .filter = RG_DISPLAY_FILTER_OFF,
         .rotation = rg_settings_get_number(NS_APP, SETTING_ROTATION, RG_DISPLAY_ROTATION_AUTO),
-        .update_mode = rg_settings_get_number(NS_APP, SETTING_UPDATE, RG_DISPLAY_UPDATE_PARTIAL),
+        .update_mode = RG_DISPLAY_UPDATE_FULL,
     };
     display = (rg_display_t){
         .screen.width = RG_SCREEN_WIDTH - RG_SCREEN_MARGIN_LEFT - RG_SCREEN_MARGIN_RIGHT,

ducalex avatar Nov 10 '22 21:11 ducalex

This was actually implemented and released in 1.41, you can now scale up or down at any factor you want.

I believe the particular commit was https://github.com/ducalex/retro-go/commit/9eb04c1efc4192d10bbde790bc388ae7ea1229ea

ducalex avatar May 03 '24 14:05 ducalex