Scaling for Hanheld system - ZFEbHVUE/Batocera-CRT-Script GitHub Wiki
๐ Table of Contents
- โ
Why We Use
pixel_aa_xform
orbox_filter_aa_xform
- ๐ Typical Handheld Native Resolutions
- ๐งฉ Why the
_xform
Shaders Matter - ๐ Special Case: Game Gear
- โก Alternative: Manual Setup (Not Recommended)
- ๐น๏ธ Example: GameBoy Advance Using a Shader
- ๐น๏ธ Example: Game Gear Using a Shader
- ๐ฎ Overlays in RetroArch Using a Shader
- โ๏ธ Example: GameBoy Advance Without Using a Shader (Not Recommended)
- โน๏ธ Super Game Boy - Not Pixel Perfect
- โก Super Game Boy - Clock Speed & Stutter
- โ When you use Scaling for Handheld System
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.
- Game Boy Advance: 240ร160
- Game Boy Color: 160ร144
- Game Gear: 160ร144 (but see note below)
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.
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.
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.
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.
- Start a game from Emulation Station
- Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
- Now back to the Main Menu
- Settings -> Video -> Scaling -> Aspect Ratio
- Set it from Core provided to Full
- Now back again to the Quick Menu
- Override -> Save Content Directory Override
- 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
- Edit the file
gba.cfg
and delete everything except these two lines:aspect_ratio_index = "24"
auto_shaders_enable = "true"
- 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
- 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
- Save the file.
- Start the GBA game again from Emulation Station
- Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
- Quick Menu -> Shaders -> Load Preset
- Navigate to the Pixel-art-scaling folder
- Then choose the
shader pixel_aa_xform.slangp
orbox_filter_aa_xform.slangp
(more lightweight)
- Go into Shader Parameters and change the following settings in this order:
- Force integer scaling horizontally = (1.00)
- Force integer scaling vertically = (1.00)
- 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.
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.
- Start a game from Emulation Station
- Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
- Now back to the Main Menu
- Settings -> Video -> Scaling -> Aspect Ratio
- Set it from Core provided to Full
- Now back again to the Quick Menu
- Override -> Save Content Directory Override
- 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
- Edit the file
gamegear.cfg
and delete everything except these two lines:aspect_ratio_index = "24"
auto_shaders_enable = "true"
- 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
- From the terminal type:
- 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
-
- Save the file.
- Start the GBA game again from Emulation Station
- Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
- Quick Menu -> Shaders -> Load Preset
- Navigate to the Pixel-art-scaling folder
- Then choose the
shader pixel_aa_xform.slangp
orbox_filter_aa_xform.slangp
(more lightweight)
- 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)
- 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.
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/
- Start a game from Emulation Station
- Go into the Quick Menu with [HOTKEY] + South button or Shift+F1
- Now back to the Main Menu
- Settings -> Video -> Scaling -> Aspect Ratio
- Set it from Core provided to custom
- Now back again to the Quick Menu
- Override -> Save Content Directory Override
- 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
- 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"
-
- 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
- From the terminal type:
- 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.
-
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:
- ๐ Pandocs Super Game Boy
- ๐ Byuuโs BSNES/Higan dev notes (archived)
- ๐ NESDev discussion
- ๐ SameBoy SGB code
- ๐ BizHawk Docs
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
- ๐ nocash Pandocs
- ๐ Byuuโs dev notes
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.