retro-go
retro-go copied to clipboard
Feature Request: Downscaling for Small Screens
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.

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. :)
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,
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