Emulation Homebrew Homebrew app UltraGB Overlay - The Game Boy / GBC emulation overlay

  • Thread starter Thread starter ppkantorski
  • Start date Start date
  • Views Views 2,424
  • Replies Replies 12
  • Likes Likes 10

ppkantorski

Ultrahand Overlay Dev
Member
Joined
May 1, 2023
Messages
177
Reaction score
368
Trophies
0
Location
CA
Website
github.com
XP
1,327
Country
United States
UltraGB Overlay


A Game Boy / Game Boy Color emulator overlay for the Nintendo Switch, built on libultrahand.



Play GB and GBC games on top of any running application.



Features

Emulation
  • Full Game Boy (DMG) and Game Boy Color (GBC/CGB) emulation via an expanded fork of Walnut-CGB (a fork of Peanut-GB)
  • Supports ROM-only, MBC1, MBC2, MBC3 (with RTC), and MBC5 (including rumble) cartridge types
  • Accurate 59.73 Hz Game Boy clock rate, decoupled from the display vsync
  • LCD ghosting / frame blending: per-game 50/50 blend of consecutive frames to reproduce phosphor persistence intended for flickering transparency effects
  • Fast-forward (4x) via ZR double-click-hold; audio pauses during fast-forward and resumes cleanly on release
  • No Sprite Limit: per-game toggle that lifts the 10-sprites-per-scanline hardware cap so flickering transparency effects show all sprites every frame

Display Modes

Overlay mode: emulator drawn inside the standard Ultrahand overlay panel (448x720 framebuffer) alongside the UltraGB menu chrome.
  • 2x pixel-perfect: 320x288 viewport with integer scale and letterboxing

Fixed overlay (default): overlay panel is anchored to the left edge of the screen, identical to all other Ultrahand overlays.

Free overlay: overlay panel floats freely anywhere on screen. Repositionable by touch hold (≈1 s) on the game screen or KEY_PLUS hold (1 s) + left stick. Position is saved between sessions.

Windowed mode: framebuffer-accurate floating window placed anywhere on screen with no UI chrome.
  • Integer scales: 1x through 6x (scale range is heap- and mode-gated; see Requirements)
  • Repositionable by touch hold (≈1 s) or KEY_PLUS hold (2 s) + left stick
  • R3 / L3 click to step scale up / down in-game (relaunches at new scale)
  • Position and scale saved to config.ini

Palette Modes

Cycled per game from the per-game settings screen. All modes work for both DMG and CGB games.
  • GBC (default): CGB games use hardware color. DMG games receive the real GBC boot ROM title-based colorization (per-game lookup from hardware-verified palette database); unrecognised or unlicensed games fall back to greyscale.
  • DMG: Classic four-shade green Game Boy LCD tint.
  • Native: True greyscale: raw luminance values, no tint.

LCD Grid Effect

Simulates the dark inter-pixel gap of a real Game Boy Color LCD by dimming the last row and column of each scaled source pixel block to approximately 12.5% brightness. Applies in both overlay and windowed modes; automatically invisible at windowed 1x.

Virtual On-Screen Controls (Overlay Mode)

D-pad, A, B, Start, and Select are drawn below the game screen and mapped to touch input each frame.

Audio
  • Game Boy volume: global GB audio output level (0–100)
  • Active Title volume: per-process master volume of the running background Switch title, controlled independently and restored automatically when the overlay closes
  • Audio Balance: per-game GB audio trim (−150% … 0% … +150%) stored in the per-game settings

Themes and Wallpapers

The overlay UI chrome (background, button colours, border) is fully themeable via .ini files placed in:
sdmc:/config/ultragb/ovl_themes/

A wallpaper (448x720 .rgba format) can be selected from:
sdmc:/config/ultragb/ovl_wallpapers/

and is displayed behind the game screen when expanded memory permits.

Default (pass-through) wallpaper mode

Shows the current Ultrahand UI wallpaper behind the overlay.



Controls

Overlay Mode (In-Game)
  • A → GB A
  • B → GB B
  • X / + → GB Start
  • Y / − → GB Select
  • D-Pad → GB D-Pad
  • Touch (virtual buttons) → GB D-Pad / A / B / Start / Select
  • ZR double-click-hold → Fast-forward (4x)
  • ZL double-click, then hold (≈0.5 s) → Toggle controller pass-through to background app
  • R3 click (solo) → Switch to free overlay mode
  • L3 click (solo) → Switch to fixed overlay mode
  • Launch combo → Return to ROM selector (normal) / close overlay (quick-launch or direct mode)

Free overlay only:
  • Touch hold on game screen (≈1 s) → Enter drag mode: move overlay, release to save position
  • KEY_PLUS hold (1 s) + left stick → Joystick reposition mode

Windowed Mode (In-Game)
  • A → GB A
  • B → GB B
  • X / + → GB Start
  • Y / − → GB Select
  • D-Pad → GB D-Pad
  • ZR double-click-hold → Fast-forward (4x)
  • ZL double-click, then hold (≈0.5 s) → Toggle controller pass-through to background app
  • Touch hold inside window (≈1 s) → Enter drag mode: move window, release to save position
  • KEY_PLUS hold (2 s) + left stick → Joystick reposition mode
  • R3 click (solo) → Step scale up (1x → 2x → … → max)
  • L3 click (solo) → Step scale down
  • Launch combo → Return to UltraGB menu / close overlay (quick-exit mode)

ROM Selector
  • A → Launch ROM
  • Y → Open per-game settings
  • Right / Configure footer → Go to Configure page
  • Left / Games footer → Return to ROM list (from Settings)
  • B → Close overlay



Save System
  • Battery saves (SRAM): written on ROM unload; stored at sdmc:/config/ultragb/saves/internal/
  • Quick-resume state: full CPU/PPU/APU snapshot saved automatically when the overlay closes; restored on next launch; stored at sdmc:/config/ultragb/states/internal/
  • User save states: 10 manual slots per game; stored at sdmc:/config/ultragb/states/
  • SRAM backup slots: 10 manual SRAM backup slots per game, independent of save states



Per-Game Settings

Press Y on any ROM in the selector to open its settings screen.
  • Save States → 10 named slots: save, load, or delete any slot
  • Save Data → 10 SRAM backup slots: manual snapshots of battery save data
  • Reset → Cold boot the game (deletes the quick-resume state)
  • Palette Mode → Cycle GBC → DMG → Native; applied live without restarting
  • No Sprite Limit → Lift the 10-sprites-per-scanline hardware cap; on by default
  • LCD Ghosting → Enable 50/50 frame blending for accurate flicker reproduction
  • Audio Balance → Per-game GB volume trim from −150% to +150%; press Y while focused to reset to 0%



Settings

Volume
  • Game Boy → GB audio output level (0–100); tap the speaker icon or press Y when focused to mute/unmute
  • Active Title → Background Switch title volume (0–100); tap the speaker icon or press Y when focused to mute/unmute; reverts to pre-game level on overlay close

Display
  • Mode → Toggle between Overlay and Windowed; takes effect on next ROM launch
  • LCD Grid → Enable/disable the LCD inter-pixel gap simulation
  • Overlay → Submenu: Position (Fixed / Free) and Theme
  • Windowed → Submenu: Scale (1x–6x, heap-gated) and Docked Resolution (720p / 1080p)

Miscellaneous
  • Quick Combo → Assign a button combo to launch directly to the last played ROM from anywhere
  • Boot Paused → Start the emulator with the game paused on launch
  • Boot Cold → Always cold-boot the game on launch (skips quick-resume state restore)
  • Button Haptics → Enable/disable rumble feedback on controller button presses
  • Touch Haptics → Enable/disable rumble feedback on screen touch (virtual buttons, drag reposition)

Overlay Submenu
  • Position → Fixed (anchored left edge) or Free (repositionable floating panel)
  • Theme → Select a UI theme from sdmc:/config/ultragb/ovl_themes/; default always available
  • Wallpaper → Select a background wallpaper from sdmc:/config/ultragb/ovl_wallpapers/ (requires 6 MB+ heap); default pass-through mode shows the current Ultrahand UI wallpaper

Windowed Submenu
  • Scale → Cycle 1x → 2x → … → max; capped by available heap and ROM size
  • Docked Resolution → 720p (default, 1.5x VI layer) or 1080p (pixel-perfect, 1:1 VI layer); takes effect on next windowed launch

Quick Combo / Quick Launch

Assigning a combo in Settings registers it system-wide and deconflicts it from other overlays and packages automatically. When triggered, the overlay launches straight into the last played ROM, bypassing the selector. The launch combo then closes the overlay entirely rather than returning to the menu.



Memory Tiers
  • 4 MB
    • Windowed max scale: 3x
    • In-game wallpaper: No
    • LCD Ghosting: No
    • Screenshots: Yes
  • 6 MB
    • Windowed max scale: 4x (5x when docked + 1080p)
    • In-game wallpaper: Yes
    • LCD Ghosting: ROMs under 2 MB only
    • Screenshots: Disabled at 5x for ROMs ≥ 2 MB
  • 8 MB
    • Windowed max scale: 5x (6x when docked + 1080p + ROM under 4 MB)
    • In-game wallpaper: Yes
    • LCD Ghosting: ROMs under 4 MB only
    • Screenshots: Disabled at 5x for ROMs ≥ 4 MB
  • 10 MB+
    • Windowed max scale: 5x (6x when docked + 1080p)
    • In-game wallpaper: Yes
    • LCD Ghosting: All ROMs
    • Screenshots: Yes

ROMs that exceed the current tier's playable size are shown in the selector with a warning colour and cannot be launched.



Requirements



Installation
  1. Download the latest ultragb.ovl from Releases
  2. Copy it to sdmc:/switch/.overlays/
  3. Launch via Ultrahand

The ROM directory defaults to sdmc:/roms/gb/ and can be changed in:
sdmc:/config/ultragb/config.ini
(rom_dir key)



Building

Requirements: devkitPro with devkitARM, libnx, and the libultrahand library.

Code:
export DEVKITPRO=/opt/devkitpro
make -j6

Output:
ultragb.ovl

The build targets C++26, ARMv8-A with SIMD/CRC/crypto extensions tuned for Cortex-A57, full LTO with 6 parallel LTRANS jobs, and links against libcurl, mbedtls, and libnx.



File Layout

Code:
sdmc:/
├── switch/
│   └── .overlays/
│       └── ultragb.ovl
├── config/
│   └── ultragb/
│       ├── config.ini              ← global settings (rom_dir, volume, scale, etc.)
│       ├── ovl_theme.ini           ← active overlay theme (copied from ovl_themes/ on select)
│       ├── ovl_wallpaper.rgba      ← active overlay wallpaper (copied from ovl_wallpapers/ on select)
│       ├── ovl_themes/             ← user-provided .ini theme files
│       ├── ovl_wallpapers/         ← user-provided .rgba wallpaper files
│       ├── saves/
│       │   └── internal/           ← pre-set SRAM battery saves
│       │   └── <game>/             ← user save-data slots
│       ├── states/
│       │   ├── internal/           ← quick-resume state (one per game, auto-managed)
│       │   └── <game>/             ← user save-state slots
│       └── settings/
│           └── <game>.ini          ← per-game settings (palette, ghosting, audio balance, etc.)
└── roms/
    └── gb/                         ← pre-set GB/GBC roms directory (.gb / .gbc only)



Credits



Contributing

Contributions are welcome! If you have any ideas, suggestions, or bug reports, please raise an issue, submit a pull request, or reach out to me directly on GBATemp.





License

This project is licensed and distributed under GPLv2.
 
Last edited by ppkantorski,
You know that not everyone is using dark theme?
 

Attachments

  • Picsew_20260409143948.jpeg
    Picsew_20260409143948.jpeg
    349.8 KB · Views: 17
This is awesome lol, there is just the tiniest little slow down / desync of audio or like idk you can definitely hear it randomly will slow down but not consistently, other than that it it's working perfect. If I could just make a suggestion though, have the option to fully close the game because I do notice it stays running in the background in a suspended state which is nice but the option to turn that off would be nice
 

Attachments

  • Snapchat-1396385911.mp4
    35.3 MB
This is awesome lol, there is just the tiniest little slow down / desync of audio or like idk you can definitely hear it randomly will slow down but not consistently, other than that it it's working perfect. If I could just make a suggestion though, have the option to fully close the game because I do notice it stays running in the background in a suspended state which is nice but the option to turn that off would be nice
I can add an option to always cold boot games you weren't just playing. One thing to note is that games don't stay running in the background, suspended state resuming just makes it feel that way. Windowed mode produces the best performance, or opaque overlay player modes, but overall it should be near 60fps, even in an active game.


Finally, I can game while I game.
View attachment 567343
Sometimes you might want to play something while you are in a different game. ¯\_(ツ)_/¯ Like for instance, in Master Duel, your opponent can be taking forever, and you might wanna do something while you wait. Or if you are just chilling somewhere in Minecraft or TOTK, you can play GB/GBC with scenery. Quick combo makes it extremely fast to pull up and hide without disrupting gameplay. Overall there are some benefits to having a GB/GBC emulator in this form factor imo.
 
  • Like
Reactions: hippy dave
UltraGB Overlay v1.0.1 is now live.

List of Changes
  1. Wallpapers are now supported on a 6 MB overlay heap size.
  2. 5x windowed mode is now supported on a 6 MB overlay heap size.
  3. 6x windowed mode is now supported on an 8 MB overlay heap size (docked + 1080p + ROM under 4 MB).
  4. Screenshots are now supported in 3x windowed mode on a 4 MB overlay heap size.
  5. Screenshots are disabled in 5x windowed mode (docked + 1080p) for ROMs ≥ 2 MB on a 6 MB heap and ROMs ≥ 4 MB on an 8 MB heap.
  6. Added Boot Paused setting: launches the emulator with the game paused.
  7. Added Boot Cold setting: always cold-boots on launch, skipping quick-resume state restore.
  8. Added default (pass-through) wallpaper mode: shows the current Ultrahand UI wallpaper.
  9. Fixed cold boot framebuffer initialization: all display modes now initialize to opaque white instead of transparent (prepacked/DMG) or black (RGB565/RGB555).
  10. Fixed title ID audio handling to avoid conflicts with sys-tune v2.1.0+r2.
 
Last edited by ppkantorski,

Site & Scene News

Popular threads in this forum