Skip to main content

Command Palette

Search for a command to run...

PKsinew Devlog # 8: Embedding mGBA and Switching Between Game and Sinew

Embedding mGBA, unifying controls, and making Sinew feel like a system

Published
4 min read
PKsinew Devlog # 8: Embedding mGBA and Switching Between Game and Sinew

By this point, Sinew could do a lot — but the experience still felt fractured.

Launching games externally meant context switching:

  • Alt-tabbing

  • Separate controller configs

  • No clean way to jump between the game and Sinew

I wanted a fast, console-like way to switch between Sinew and whatever game was running — something closer to a Home button than a desktop workflow.


The External mGBA Problem

Using external mGBA, this is technically possible via its scripting API.
The idea would be:

  • Run mGBA as a separate process

  • Use its scripting hooks

  • Spin up a Node.js server

  • Listen for controller button combinations

  • Send commands back to mGBA

It works — but it’s messy.

It adds:

  • Extra services

  • Network plumbing

  • More failure points

And it didn’t feel right for what Sinew was becoming.


Thinking Like RetroArch

That’s when I started thinking about how RetroArch does things.

RetroArch embeds emulators directly using libretro cores, which expose:

  • Video frame buffers

  • Audio buffers

  • Input callbacks

So I wondered:

What if I embed the mGBA libretro core directly inside Sinew?

In theory, Python could do this.

In practice… it was rough.


First Attempts (and Shelving It)

I’d played around with this earlier while I was out of Claude tokens, using ChatGPT.

I managed to:

  • Get the frame buffer rendering into a Pygame surface after some trial and error

  • Get input mostly working

  • Get audio, but it was extremely choppy

  • Break save handling completely

It worked, but it didn’t feel stable or shippable — so I shelved it.


Claude to the Rescue (Again)

Later on, I dropped the same code into Claude and asked it to take a look.

Within minutes:

  • The audio bitrate was corrected

  • Audio became silky smooth immediately

  • Save handling was fixed

That was all I needed.

At that point, embedding the emulator directly into Sinew became viable.


Embedding mGBA Into Sinew

Once embedded, everything started to fall into place:

  • The emulator now uses Sinew’s ROM paths and save paths

  • A unified button mapper controls both:

    • Sinew UI

    • The running game

I wired in a Start + Select combo that instantly switches between:

  • The game

  • The Sinew menu

From there, I added guardrails:

  • You can’t launch another game while one is running

  • Sinew offers:

    • Return to game

    • Stop game

  • The button combo works globally

At this point, Sinew finally felt cohesive.


Catching Up to Today

This devlog is now starting to catch up to the present.

Today, I added:

  • An option to change the button combo

  • Support for using a single custom “Home” button

This matters because:

  • GBA doesn’t have many buttons

  • Many controllers do have Home buttons

  • Some only have just enough buttons

Flexibility here was important.


The Bug You Only Find by Playing

After all that, I did the sensible thing.

I kicked back, loaded up FireRed, and relaxed before heading to a Christmas party.

Five minutes in — the audio died.

Turns out the issue was subtle:

  • The emulator was producing audio faster than it was being consumed

  • Unused audio chunks were queuing up

  • Once the queue filled, audio playback crashed

The fix was simple but necessary:

  • Keep a small audio buffer

  • If more than a few chunks are waiting, discard the oldest unused audio data

In other words:

Better to drop stale audio than let it pile up and kill sound entirely.

Problem solved.


Where This Leaves Sinew

At this point, Sinew can:

  • Launch games internally

  • Switch instantly between game and UI

  • Share controller mappings across both

  • Enforce safe rules around save access

  • Recover gracefully from real-world edge cases

This is the point where Sinew stopped feeling like a tool and started feeling like a system.


Next Up

  • Settings

  • Themes

  • Mass Pokémon storage

And then… polishing.