jpolo1224 d1e1d9975b Input: connect vibration, which was three unconnected halves
Rumble did nothing in any game. Everything needed for it existed and none of
it was wired to anything else.

The core side was fine throughout: the virtual pad is created with
CELL_PAD_CAPABILITY_ACTUATOR, its two VibrateMotors are initialised, and
_rpcsx_getPadRumble reads them, so cellPadSetActDirect had somewhere to land.

Above that, three dead links in a row.

The pump that polls getPadRumble and drives the phone's vibrator was written
and never started -- startRumblePump had no callers at all. The core cannot
notify the JNI layer when the guest writes the motors, so with nothing
polling, no guest rumble could ever reach the device. It now runs for the VM's
lifetime, started once the emulator is past boot and stopped in a finally, so
the abnormal-teardown path that exits via stopRequested cannot leave the motor
buzzing on whatever value a dead guest last wrote.

The enable flag was two flags. NativeApp.sRumbleEnabled had three writers --
the settings toggle, the in-game menu and app start -- and no readers. The
pump consulted a private copy in Rpcs3Bridge that only setPadVibration wrote,
and setPadVibration had no callers either. So the toggle wrote one store and
the pump read another. There is one flag now; the private copy is a read-only
accessor onto it.

Rumble is polled on port 0 only. The device has one vibrator, so there is
nothing to spend a second port on.
2026-08-19 21:25:47 -04:00
2026-07-31 18:41:29 +02:00
2026-06-14 16:05:41 +02:00
2024-12-28 19:58:59 +01:00
2024-11-16 15:10:20 +01:00
2025-11-02 14:22:11 +02:00
2026-08-18 16:30:45 -04:00
2026-06-21 16:37:09 +02:00

ARMSX3

Uses the latest RPCS3 upstream code (the recent ARM64 improvements included).

Building

arm64-v8a and armv8.2 is supported. You need the Android SDK with NDK r27 or newer, CMake 3.30 or newer, and a JDK 17. Android Studio ships all of these.

Clone with submodules, then fetch the two third party checkouts that are not submodules:

git clone --recursive https://github.com/ARMSX2/ARMSX3.git
cd ARMSX3
git clone https://github.com/SnowflakePowered/librashader 3rdparty/librashader
git clone https://github.com/bylaws/libadrenotools android/armsx3-ui/app/src/main/cpp/libadrenotools

Build the core. This is the long part and produces an unstripped library of around 1.3 GB:

export ANDROID_HOME=$HOME/Library/Android/sdk
cmake -B build-android -G Ninja \
  -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake \
  -DANDROID_ABI=arm64-v8a -DANDROID_PLATFORM=android-31 \
  -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build-android --target rpcsx-android -j8

Strip it and put it where the app expects it:

llvm-strip --strip-unneeded build-android/android/libarmsx3-core.so
cp build-android/android/libarmsx3-core.so \
   android/armsx3-ui/app/src/main/jniLibs/arm64-v8a/

Then build the app:

cd android/armsx3-ui
export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
./gradlew :app:assembleRelease

The apk lands in app/build/outputs/apk/release/.

Note that the core library has to be rebuilt and copied again whenever anything under rpcs3/ or android/src/ changes. Gradle does not build it for you.

The Discord Social SDK is proprietary and is not redistributed here. Get it from Discord's developer portal and drop it in app/libs/ and app/src/main/cpp/discord_sdk/ if you want that feature. The build skips it otherwise.

Running it needs PS3 firmware, which is not included. License

GPL-2.0-only, the same as RPCS3. See LICENSE. Some files may be licensed differently, check the file headers.

Based on RPCS3, https://github.com/RPCS3/rpcs3

S
Description
No description provided
Readme GPL-2.0
154 MiB
Languages
C++ 77.3%
Kotlin 13.4%
C 7.2%
Self 0.7%
GLSL 0.5%
Other 0.9%