Scaling for Hanheld system - ZFEbHVUE/Batocera-CRT-Script GitHub Wiki

๐Ÿ” Scaling for Handheld Systems

๐Ÿ“‘ Table of Contents
  1. โœ… Why We Use pixel_aa_xform or box_filter_aa_xform
  2. ๐Ÿ“ Typical Handheld Native Resolutions
  3. ๐Ÿงฉ Why the _xform Shaders Matter
  4. ๐Ÿ“Œ Special Case: Game Gear
  5. โšก Alternative: Manual Setup (Not Recommended)
  6. ๐Ÿ•น๏ธ Example: GameBoy Advance Using a Shader
  7. ๐Ÿ•น๏ธ Example: Game Gear Using a Shader
  8. ๐ŸŽฎ Overlays in RetroArch Using a Shader
  9. โš™๏ธ Example: GameBoy Advance Without Using a Shader (Not Recommended)
  10. โ„น๏ธ Super Game Boy - Not Pixel Perfect
  11. โšก Super Game Boy - Clock Speed & Stutter
  12. โœ… When you use Scaling for Handheld System

โœ… Why We Use pixel_aa_xform or box_filter_aa_xform

For handheld systems, we do not upscale the native resolution to fill the whole screen.
Instead, we display the original handheld image inside a larger CRT mode (typically 320ร—240) while keeping the native pixels intact.


๐Ÿ“ Typical Handheld Native Resolutions

  • Game Boy Advance: 240ร—160
  • Game Boy Color: 160ร—144
  • Game Gear: 160ร—144 (but see note below)

๐Ÿงฉ Why the _xform Shaders Matter

We use pixel_aa_xform or box_filter_aa_xform with the _xform transform pass only, to:

  • Force integer scaling when needed.
  • Lock the correct aspect ratio.
  • Position the native image inside the CRT canvas without unwanted stretching.
  • No smoothing or filtering is applied โ€” only the transform part is used.

These shaders were created by fishcu to solve tricky cases like Game Gear stretching without manual aspect hacks.


๐Ÿ“Œ Special Case: Game Gear

Game Gear is unique:

  • Internally renders at 160ร—144.
  • Original hardware stretches this horizontally to 4:3 on the Game Gear LCD.
  • So the internal aspect is closer to 10:9, but the final output is displayed stretched.

The _xform shaders handle this for you automatically.
Manual aspect correction in RetroArch is tedious and easily breaks.


โšก Alternative: Manual Setup (Not Recommended)

You can do this manually by adjusting integer scale, aspect ratio, and overscan โ€”
but itโ€™s more work and easily breaks the Game Gear stretch or handheld positioning.

๐Ÿ“„ See manual example


In short:
The _xform shaders keep the handheld image pixel-perfect, correctly positioned and scaled, with minimum hassle โ€” especially for special cases like Game Gear.

Example GameBoy Advance using a Shader

  1. Start a game from Emulation Station
  2. Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
  3. Now back to the Main Menu
  4. Settings -> Video -> Scaling -> Aspect Ratio
  5. Set it from Core provided to Full
  6. Now back again to the Quick Menu
  7. Override -> Save Content Directory Override
  8. Exit out from the emulator and go into the newly created folder named in this example to VBA-M in the folder /userdata/system/configs/retroarch/config
  9. Edit the file gba.cfg and delete everything except these two lines:
    • aspect_ratio_index = "24"
    • auto_shaders_enable = "true"
  10. Now let's make a switchres.ini override file:
  • From the terminal type:
    cp /etc/switchres.ini /userdata/system/configs/retroarch/config/VBA-M/gba.switchres.ini
  1. Edit the file gba.switchres.ini
    Find the line:
  • user_mode auto
    Change it to:
  • user_mode 320x240
  • You can also use super resolutions if you want a little bit crisper image.
    • 320*8 = 2560
  • user_mode 2560x240 Also change this:
  • dotclock_min 0
    To this:
  • dotclock_min 25.0
  1. Save the file.
  2. Start the GBA game again from Emulation Station
  3. Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
  4. Quick Menu -> Shaders -> Load Preset
  • Navigate to the Pixel-art-scaling folder
  • Then choose the shader pixel_aa_xform.slangp or box_filter_aa_xform.slangp (more lightweight)
  1. Go into Shader Parameters and change the following settings in this order:
  • Force integer scaling horizontally = (1.00)
  • Force integer scaling vertically = (1.00)
  1. Go out of the Shader Parameters and save the shader setting.
  • Shaders -> Save Preset -> Save Content Directory Preset
  • The file named gba.slangp will now be saved to the directory /userdata/system/configs/retroarch/config/VBA-M
  • Next time you load up any GameBoy Advance game, the settings will be applied to all games.

Example Game Gear using a Shader

Game Gear is a special case since it needs to be stretched to 4:3.
The original hardware internally outputs 160x144 pixels, then horizontally stretched to 4:3 on the hardware while the internal aspect ratio is 10:9.

  1. Start a game from Emulation Station
  2. Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
  3. Now back to the Main Menu
  4. Settings -> Video -> Scaling -> Aspect Ratio
  5. Set it from Core provided to Full
  6. Now back again to the Quick Menu
  7. Override -> Save Content Directory Override
  8. Exit out from the emulator and go into the newly created folder named in this example to Genesis Plus GX in the folder /userdata/system/configs/retroarch/config
  9. Edit the file gamegear.cfg and delete everything except these two lines:
    • aspect_ratio_index = "24"
    • auto_shaders_enable = "true"
  10. Now let's make a switchres.ini override file:
    • From the terminal type:
      cp /etc/switchres.ini /userdata/system/configs/retroarch/config/Genesis Plus GX/gamegear.switchres.ini
  11. Edit the file gamegear.switchres.ini
    Find the line:
    • user_mode auto
      Change it to:
    • user_mode 320x240
    • You can also use super resolutions if you want a little bit crisper image.
      • 320*8 = 2560
    • user_mode 2560x240 Also change this:
    • dotclock_min 0
      To this:
    • dotclock_min 25.0
  12. Save the file.
  13. Start the GBA game again from Emulation Station
  14. Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
  15. Quick Menu -> Shaders -> Load Preset
    • Navigate to the Pixel-art-scaling folder
    • Then choose the shader pixel_aa_xform.slangp or box_filter_aa_xform.slangp (more lightweight)
  16. Go into Shader Parameters and change the following settings in this order:
    • Force aspect ratio = (0.00)
    • Horizontal aspect ratio = (4.00)
    • Vertical aspect ratio = (3.00)
    • Force integer scaling vertically = (1.00)
  17. Go out of the Shader Parameters and save the shader setting.
    • Shaders -> Save Preset -> Save Content Directory Preset
    • The file named gamegear.slangp will now be saved to the directory /userdata/system/configs/retroarch/config/Genesis Plus GX
    • Next time you load up any Game Gear game, the settings will be applied to all games.

Overlays in RetroArch using a Shader

Edit the file *.*.cfg and add these lines:

  • aspect_ratio_index = "24"
  • auto_shaders_enable = "true"
  • input_osk_overlay_opacity = "0.700000"
  • input_overlay = "~/configs/retroarch/overlays/borders/overlay_name.cfg"
  • input_overlay_enable = "true"
  • input_overlay_enable_autopreferred = "true"
  • input_overlay_opacity = "0.700000"
  • input_overlay_scale_landscape = "1.000000"
  • input_overlay_scale_portrait = "1.000000"
  • input_overlay_behind_menu = "true"

Overlays are in the folder /userdata/system/Batocera-CRT-Script/extra/overlays
Copy the borders folder to /userdata/system/configs/retroarch/overlays/


Example GameBoy Advance - Without Using a Shader (Not Recommended)

  1. Start a game from Emulation Station
  2. Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
  3. Now back to the Main Menu
  4. Settings -> Video -> Scaling -> Aspect Ratio
  5. Set it from Core provided to custom
  6. Now back again to the Quick Menu
  7. Override -> Save Content Directory Override
  8. Exit out from the emulator and go into the newly created folder named in this example to VBA-M in the folder /userdata/system/configs/retroarch/config
  9. Edit the file gba.cfg and delete everything except this line:
    • aspect_ratio_index = "23" Then add these 4 lines:
    • menu_linear_filter = "true"
    • custom_viewport_height = "160"
    • custom_viewport_width = "240"
    • video_scale_integer = "true"
  10. Now let's make a switchres.ini override file:
    • From the terminal type:
      cp /etc/switchres.ini /userdata/system/configs/retroarch/config/VBA-M/gba.switchres.ini
  11. Edit the file gba.switchres.ini
    Find the line:
    • user_mode auto
      Change it to:
    • user_mode 320x240
    • You can also use super resolutions if you want a little bit crisper image.
      • 320*8 = 2560
    • user_mode 2560x240 Also change this:
    • dotclock_min 0
      To this:
    • dotclock_min 25.0
    • Next time you load up any GameBoy Advance game, the settings will be applied to all games.

Super Game Boy - Not Pixel Perfect

The original Super Game Boy (SGB) and Super Game Boy 2 display Game Boy games with an incorrect aspect ratio.
The Game Boyโ€™s true native resolution is 160ร—144, but the SGB scales this image up to ~180ร—160 to fit the SNESโ€™s 256ร—224 output mode.
This stretches the pixels horizontally and vertically to fill the TV screen better โ€” but means the pixels are no longer square or 1:1.

This is not a quirk of emulators โ€” itโ€™s exactly how the original hardware worked:

Super Game Boy - Clock Speed & Stutter

The original Super Game Boy (SGB) did not just stretch the Game Boyโ€™s native 160ร—144 image โ€”
it also ran the Game Boy hardware at the wrong speed.

The SGB used the SNESโ€™s master clock, which didnโ€™t match the Game Boyโ€™s exact 4.194โ€ฏMHz clock.
As a result, all games ran about 2.4% too fast, making both gameplay and music slightly higher pitched.

Nintendo fixed this with the Super Game Boy 2, which added an extra crystal oscillator for correct timing.
However, the stretched aspect ratio remained, and there is still a tiny bit of video stutter because of how the SNES syncs the Game Boyโ€™s output to the TV.

Important:
If you run Super Game Boy emulation today โ€” for example, using Mesen-S, bsnes, or any SNES core in SGB mode โ€”
youโ€™ll reproduce the same quirks:

  • The aspect ratio stretch
  • The original clock speed error (if the emulator replicates real hardware faithfully)
  • The possible micro stutter due to how the SNES PPU handles Game Boy frames


โœ… When you use Scaling for Handheld System

When you use Scaling for Handheld System, it does none of this:

  • The Game Boy core runs at the true clock speed.
  • The resolution is pixel-perfect, unstretched.
  • The output matches the CRTโ€™s refresh for smooth scrolling.

Result: You get true-to-original handheld playback โ€” no speedup, no stretch, no unnecessary stutter.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ