Skip to content

Add Pocket Emu handheld emulator app - #161

Draft
octobooth-13 wants to merge 2 commits into
badger:mainfrom
octobooth-13:add-game-boy-app
Draft

octobooth-13 wants to merge 2 commits into
badger:mainfrom
octobooth-13:add-game-boy-app

Conversation

@octobooth-13

@octobooth-13 octobooth-13 commented Oct 29, 2026 •

Copy link
Copy Markdown

What does this PR do?

Adds Pocket Emu (badge/apps/pocket_emu), an app that plays classic 8-bit handheld games on the Universe 2026 badge. It runs .gb ROM files that the owner dumps from their own cartridges and copies to apps/pocket_emu/roms/ in USB Disk Mode. No ROMs are included, and roms/ is git-ignored.

Python is far too slow for emulation, so the emulator is Peanut-GB (MIT), wrapped as a MicroPython native module:

  • tools/pocket_emu/gbcore.c holds the wrapper, peanut_gb.h is vendored at commit d0bcca7, and build.py builds badge/apps/pocket_emu/gbcore.mpy without needing make.
  • The module targets armv7emsp, .mpy v6.3, which matches stock firmware (sys.implementation._mpy == 7942, pimoroni/micropython bw-1.29.0-gc). No firmware change is needed.
  • The core draws straight into the HIRES RGB565 screen buffer, scaled 1.5x (sharp or smoothed) or at 1x.

How the app behaves:

  • Speed: games run at full speed (59.7 emulated fps). Each display update runs as many emulated frames as real time requires, and Peanut-GB skips line rendering for the frames that are not shown.
  • Saves: battery saves go to /state/pocket_emu/<rom>.sav. A 32 KB write stalls the badge for about 0.5 s, so the core reports which 8 KB RAM banks changed. Changes outside bank 0 (real save data) are written about 1 s after the game stops writing. Bank-0-only changes, which some games use as scratch space for sprites, are written at most once a minute, and always when HOME or quit is pressed. A .sav placed next to a ROM is imported on first launch.
  • HOME: opens a pause menu with colours (automatic per-game palettes, classic green, grey), pixel style, speed (normal or 2x) and Save and quit. The app turns off the default HOME exit, as rogue and input_test do, so a game is never closed with unsaved progress.
  • No sound: the badge has no speaker.

Type of change

  • New badge app
  • Improvement or bug fix to an existing app
  • Firmware, menu, or system change
  • Documentation
  • Infrastructure (workflows, scripts, tooling)
  • Universe 2025 (badge25/) maintenance

Badge app checklist

  • The app lives in badge/apps/<name>/ with __init__.py and a 24x24 icon.png (it is 48x48, which badge/AGENTS.md recommends for a sharper tile)
  • README.md starts with a one-sentence description, followed by usage and any hardware or network requirements
  • Uses the 2026 runtime globals (badge, screen, image, ...) and logical buttons such as BUTTON_SELECT
  • Movement and animation are frame-rate independent (badge.ticks_delta)
  • Tested on Universe 2026 badge hardware, including both orientations and the capacitive controls
  • Assets are in assets/, are PNG where possible, and are as small as practical
  • No secrets, tokens, or personal data are committed (badge/secrets.py stays empty)

Screenshots

Game picker at 320x240

The game names in the screenshot are placeholders. Gameplay screenshots are left out because they would show third-party game artwork.

How to use it

Copy .gb files into apps/pocket_emu/roms/ on the BADGER drive, then open Pocket Emu. With one ROM it starts straight away; with several, pick one from the list.

Badge Handheld
Direction buttons or touch pad D-pad
SELECT A
BACK B
MENU (tap) START
MENU (hold) SELECT
HOME Pause menu (colours, pixels, speed, Save and quit)

Monochrome-era and dual-mode cartridges work. Colour-only games do not.

Licensing and intellectual property

This is an open source repository released under the MIT License. Everything merged here is distributed under the terms of that license.

We can't accept contributions that use someone else's intellectual property (for example, characters, artwork, logos, trademarks, game names, music, fonts, or code) unless that person or company has agreed to its release under the project license. This includes recognizable likenesses of existing games or brands that could be confusing.

  • I created all code and assets in this PR, or they are already available under an MIT-compatible license and I have credited them in the app README
  • This PR doesn't include third-party characters, logos, trademarks, or other IP, or the owner has agreed to its release under the MIT License
  • I agree that my contribution is licensed under this project's MIT License

Additional notes

  • Rebrand: the first commit used a trademarked product name, a lookalike icon and game names. The second commit renames the app to Pocket Emu, draws a new generic handheld icon, and removes those names from the UI, READMEs and comments. The only remaining mentions are in the vendored, unmodified peanut_gb.h, whose MIT licence header and docs describe the hardware it emulates.
  • Code licensing: all code is new or MIT-licensed. Peanut-GB is credited in both READMEs, and the per-game palette values come from its SDL example (MIT), credited in a code comment.
  • Hosting: whether this repository should host an emulator at all is a policy call for maintainers.
  • Binary file: gbcore.mpy is a compiled binary, reproducible with tools/pocket_emu/build.py; rebuilding after the rename produced a byte-identical file. It only loads on firmware with a matching .mpy ABI. Elsewhere, including the Badge Simulator, the app shows an "emulator core did not load" screen instead of crashing.

Validation

  • python .github/scripts/validate_app_readmes.py badge/apps: passed ("All app READMEs have a valid description.")
  • python .github/skills/hyb26-skill/scripts/validate_app.py badge/apps/pocket_emu: passed (0 warnings)
  • Badge Simulator check_app: passed, with one warning that icon.png is 48x48. The picker renders in the simulator, which cannot run native .mpy code.
  • Hardware: tested on a Universe 2026 badge (MicroPython 1.29.0-preview, RP2350 at 230 MHz) before the rename. The rename changed only names, paths and strings; the core binary is identical.
    • Scripted inputs: game picker, loading, gameplay, the pause menu and settings changes. Gameplay held 59–61 emulated fps; the screen updated 42–45 fps in light scenes and 22–37 fps in the heaviest scene.
    • Save round trip: a new game was saved in-game. The write landed outside bank 0, and after reloading the save the game offered CONTINUE.
    • Install: the app was installed through USB Disk Mode and the badge rebooted to the menu.
    • By hand: the author has played it on the badge, including upside down and with the capacitive touch pads.

octobooth-13 and others added 2 commits October 29, 2026 10:16
Adds badge/apps/game_boy, which runs original Game Boy ROMs that the owner
copies onto the badge. The emulator core is Peanut-GB (MIT), wrapped as a
MicroPython native module (gbcore.mpy) built from tools/gameboy for the
RP2350 (armv7emsp, .mpy v6.3). No ROMs are included; roms/ is git-ignored.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Renames badge/apps/game_boy to badge/apps/pocket_emu and tools/gameboy to
tools/pocket_emu, replaces the handheld-likeness icon with a generic one, and
removes trademarked product and game names from the UI, READMEs and
comments, as the repository's IP policy requires. Behaviour and the
compiled core are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@octobooth-13 octobooth-13 changed the title Add Game Boy emulator app Add Pocket Emu handheld emulator app Oct 29, 2026
@octobooth-13 octobooth-13 reopened this Oct 29, 2026
@octobooth-13

Copy link
Copy Markdown
Author

Hi maintainers! 👋 This PR is ready for review, but my account can only open draft pull requests here: marking it ready, or reopening it as a non-draft, fails with a permissions error. Could someone please mark it Ready for review, approve the CI workflow run for this fork, and take a look?

Quick summary for reviewers:

  • What it is: Pocket Emu, an app that plays classic 8-bit handheld games on the Universe 2026 badge, using the MIT-licensed Peanut-GB emulator as a native .mpy module. No firmware change is needed.
  • No game files or third-party branding: no ROMs are included (roms/ is git-ignored; people add dumps of cartridges they own). The app was rebranded in the second commit to remove trademarked product and game names and the lookalike icon.
  • Tested on a badge: full-speed gameplay, the pause menu, in-game save and reload, and install through USB Disk Mode.

Whether this repo should host an emulator is your call, and I'm happy to make any changes you'd like. Thanks!

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant