3 Commits
Author SHA1 Message Date
jpolo1224 c1781b95cb Connect the keyboard to the emulator
The keyboard setting, the on-screen keyboard hotkey, the touch button and the
IME plumbing all worked. Nothing behind them did, in three separate places:

  - init_kb_handler installed NullKeyboardHandler unconditionally, so cellKb --
    the API games actually read a keyboard through -- reported none attached no
    matter what the UI said.
  - NativeApp.usbKeyboardKey and usbSetKeyboardEnabled were Unsupported.note()
    stubs. Every keystroke went into a no-op that returned false.
  - The setting wrote [USB1] Type = hidkbd, which is PCSX2's emulated USB HID
    keyboard. There is no such device in this core -- "hidkbd" appears nowhere
    in it -- so that write only ever reached Unsupported.note("USB1/Type").

All three are inherited from the UI port, which is why the feature looked whole.

The desktop handler is a QObject that installs an event filter on a QWindow, so
none of it survives the port. It does not need to: everything that turns a key
into cellKb data already lives in KeyboardHandlerBase::HandleKey, and a concrete
handler owes it exactly one thing, a populated qt_code -> CELL_KEYC map.
virtual_keyboard_handler builds that map with the Qt key codes as literals, and
translates Android keycodes onto it -- including left/right modifiers, which have
to come back in the native_key encoding get_out_key_code compares against or
every modifier reads as the right-hand one.

The setting now writes Input/Output/Keyboard, which is what the core reads. That
happens once, in Emulator::Load, so it applies on the next boot rather than to a
game already running; the description says so now, because the old comment
claimed a live attach that never existed.

KeyEvent.getUnicodeChar() is carried through as well. cellKb derives its own
character from the raw code plus the live modifier state and does not need it,
but the emulator's own overlay text entry matches on the string.
2026-08-19 10:39:08 -04:00
jpolo1224 812ef3763b Bundle bagas' controller skins and preview every built-in one
Adds two packs from bagas as app assets, ARMSX3 Textured and ARMSX1, and makes
ARMSX3 Textured what a fresh install gets. The order offered is ARMSX3 Textured,
ARMSX2, ARMSX1, NetherSX2, NetherSX2 Old. Their files arrive named plainly
(L1.png, cross.png), which the loader already handles: it strips ic_controller_
and a trailing _button, so they are renamed to the canonical form on the way in
and both packs land on exactly the key set nethersx2 uses.

The default needed untangling first. Null meant the built-in ARMSX2 drawables
AND was what an install with no stored choice got, so the two were the same
thing and nothing had to tell them apart. They are different now. Resolution
moved into one function both callers use, because ensureLoaded and
applyForSerial each resolved separately and disagreeing would have changed the
pad the first time a game started:

  nothing stored  the default, ARMSX3 Textured
  NONE            the ARMSX2 row was chosen, so the drawables
  an id           that skin, or the default if it names one no longer installed

setActive stores NONE at the global tier rather than removing the key. Removing
it used to mean the drawables; with a bundled default it would now mean "never
chose", so picking ARMSX2 would have silently handed back ARMSX3 Textured on the
next launch. Nobody's existing choice moves: only the absence of a stored value
resolves to the default, and that is not written back, so the default can change
again later without pinning every install to today's answer.

Every built-in now shows a preview strip beside its name, matching what the
downloader already does for remote skins. Baked in as preview.png per pack
rather than composed at runtime: the list draws several at once and compositing
ten bitmaps per row per recomposition is not worth it for a picture that never
changes. keyForFilename ignores the file, so it is not counted as a button. The
ARMSX2 look has no asset folder, so its strip is a drawable.

ARMSX3 Dark was offered and is deliberately not included. It ships 17 images
against the other packs' 18, with no start button.

Verified in the APK rather than assumed: four asset packs present, 18 images
each in the two new ones, four asset previews plus the drawable.
2026-08-08 22:30:30 -04:00
jpolo1224 1eb63137e3 ARMSX3: Android port of RPCS3, proof of concept
Adds an Android build of the RPCS3 core plus a Compose UI, and fixes several
things that stopped it working on ARM64.

Renderer:
- Emit concrete bounds for runtime sized arrays in uniform blocks when
  VK_EXT_shader_uniform_buffer_unsized_array is missing. Adreno does not have
  the extension, so every game pipeline failed with VK_ERROR_UNKNOWN and only
  overlays drew.
- Probe and request that extension properly instead of chaining its feature
  struct unconditionally.
- Hand VMA the Vulkan function pointers it needs under VK_NO_PROTOTYPES.
- Rebuild the surface and swapchain when the window is lost instead of killing
  the RSX thread.
- Only create a GLES context when the GL renderer is actually selected.

SPU:
- Sum instead of taking an absolute difference in the ARM64 block verification
  checksum. The difference collides on the near identical job binaries an SPU
  job manager streams through one local store address, so a cached block could
  run against another job's code.

Threading:
- Implement thread affinity on Android using sched_setaffinity.
- Add an ARM big.LITTLE core arrangement so SPU and RSX threads land on the
  fast cores.

Misc:
- Detect the host CPU for the LLVM JIT instead of pinning cortex-a34.
- Fall back to the default audio device when cubeb cannot enumerate.
2026-08-06 08:59:52 -04:00