mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
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.
172 lines
8.6 KiB
CMake
172 lines
8.6 KiB
CMake
# ARMSX3: the Android shared library, built on UPSTREAM RPCS3.
|
|
#
|
|
# NOTE ON LAYOUT (this is the important part):
|
|
# RPCSX makes android/ the top-level CMake project and does
|
|
# `add_subdirectory(..)` to pull the emulator in. That does not work against
|
|
# upstream, because upstream assumes CMAKE_SOURCE_DIR == repo root in at least
|
|
# four places -- buildfiles/cmake/FindWolfSSL.cmake, buildfiles/cmake/FindZLIB.cmake,
|
|
# 3rdparty/protobuf/CMakeLists.txt and 3rdparty/llvm/CMakeLists.txt all build
|
|
# paths as ${CMAKE_SOURCE_DIR}/3rdparty/... . Configuring from android/ makes
|
|
# every one of those resolve to android/3rdparty/... and fail.
|
|
#
|
|
# So here the repo ROOT stays the top-level project and this is an ordinary
|
|
# subdirectory, added from the root CMakeLists behind `if(ANDROID)`. Build
|
|
# option overrides are passed on the cmake command line (-D...) rather than
|
|
# set() here, since they must be visible before add_subdirectory(3rdparty).
|
|
#
|
|
# Upstream's core target is `rpcs3_emu`. Upstream's rpcs3/CMakeLists.txt already
|
|
# guards Qt / rpcs3qt / rpcs3_lib / the rpcs3 executable behind `if (NOT ANDROID)`
|
|
# while calling `add_subdirectory(Emu)` unconditionally, so a core-only Android
|
|
# configuration is something upstream half-supports already.
|
|
|
|
# rpcs3/Input/ is not a library upstream -- its sources are compiled straight
|
|
# into the `rpcs3` executable, which lives inside `if (NOT ANDROID)`. So on
|
|
# Android nothing builds them, yet rpcs3_emu references pad_thread and
|
|
# ps_move_tracker (cellPad's LDD pad API, cellGem's tracker), and the link fails
|
|
# with undefined symbols. Build the platform-safe subset here.
|
|
#
|
|
# Deliberately EXCLUDED, and why:
|
|
# evdev_/xinput_/mm_/sdl_* - Linux/Windows/SDL backends, all disabled
|
|
# basic_keyboard_/basic_mouse_/
|
|
# keyboard_pad_/raw_mouse_/
|
|
# gui_pad_thread/mouse_gyro_ - Qt-dependent (rpcs3qt is not built here)
|
|
# camera_video_sink - Qt multimedia
|
|
set(ARMSX3_INPUT_SOURCES
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/pad_thread.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/product_info.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/hid_pad_handler.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/ds3_pad_handler.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/ds4_pad_handler.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/dualsense_pad_handler.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/skateboard_pad_handler.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/ps_move_handler.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/ps_move_config.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/ps_move_calibration.cpp
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/ps_move_tracker.cpp
|
|
# pad_thread references mouse_gyro_handler directly, so it is not optional
|
|
# despite the "mouse" name.
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/mouse_gyro_handler.cpp
|
|
# Ours: on-screen touch controls.
|
|
${CMAKE_SOURCE_DIR}/rpcs3/Input/virtual_pad_handler.cpp
|
|
)
|
|
|
|
add_library(rpcsx-android SHARED
|
|
src/rpcsx-android.cpp
|
|
# Carried from RPCSX; no upstream equivalent.
|
|
${CMAKE_SOURCE_DIR}/rpcs3/dev/iso.cpp
|
|
${ARMSX3_INPUT_SOURCES}
|
|
# rpcs3::get_version() and friends. Like Input/, this is compiled into the
|
|
# `rpcs3` executable upstream, not into rpcs3_emu, so Android never gets it.
|
|
${CMAKE_SOURCE_DIR}/rpcs3/rpcs3_version.cpp
|
|
)
|
|
|
|
# Ship as libarmsx3-core.so, which is the name the app calls
|
|
# System.loadLibrary("armsx3-core") for. Setting OUTPUT_NAME (rather than
|
|
# renaming the file after the fact) also fixes the SONAME, so the file name and
|
|
# the name the dynamic linker registers it under agree -- a mismatch there works
|
|
# by luck for a plain dlopen and stops working the moment anything resolves it
|
|
# by soname.
|
|
set_target_properties(rpcsx-android PROPERTIES OUTPUT_NAME armsx3-core)
|
|
|
|
target_compile_features(rpcsx-android PRIVATE cxx_std_23)
|
|
|
|
# The librashader upscaler lives in rpcs3/Emu/RSX/VK/, i.e. it compiles into
|
|
# rpcs3_emu -- not into this target -- so the header search path has to be added
|
|
# there. This directory is processed after add_subdirectory(rpcs3), so the target
|
|
# already exists. librashader_ld.h is a header-only permissive loader that
|
|
# dlopen()s librashader.so at runtime; nothing MPL-licensed is linked in. See the
|
|
# licensing note at the top of upscalers/librashader_pass.h.
|
|
target_include_directories(rpcs3_emu PRIVATE
|
|
${CMAKE_SOURCE_DIR}/3rdparty/librashader/include
|
|
)
|
|
|
|
target_include_directories(rpcsx-android PRIVATE
|
|
${CMAKE_SOURCE_DIR}
|
|
${CMAKE_SOURCE_DIR}/rpcs3
|
|
${CMAKE_SOURCE_DIR}/3rdparty/librashader/include
|
|
# rpcsx-android.cpp pulls in Input/hid_pad_handler.h (DS3/DS4/DualSense
|
|
# over USB) and hidapi_libusb.h/libusb.h directly. rpcs3_emu links these
|
|
# PRIVATE, so their include dirs do not propagate to us.
|
|
${CMAKE_SOURCE_DIR}/3rdparty/hidapi/hidapi/hidapi
|
|
${CMAKE_SOURCE_DIR}/3rdparty/hidapi/hidapi/libusb
|
|
${CMAKE_SOURCE_DIR}/3rdparty/libusb/libusb/libusb
|
|
# Utilities/bin_patch.h (patch_engine) includes util/yaml.hpp, which includes
|
|
# yaml-cpp. rpcs3_emu links yaml-cpp PRIVATE, so it does not propagate here.
|
|
${CMAKE_SOURCE_DIR}/3rdparty/yaml-cpp/yaml-cpp/include
|
|
)
|
|
|
|
target_link_libraries(rpcsx-android
|
|
rpcs3_emu
|
|
# ps_move_tracker/ps_move_calibration use the Fusion AHRS solver. rpcs3_lib
|
|
# links this upstream; we build those Input sources ourselves, so we need it.
|
|
3rdparty::fusion
|
|
# The HID pad handlers (DS3/DS4/DualSense/skateboard/PS Move) are ours to
|
|
# build here, so hidapi + libusb are ours to link too.
|
|
3rdparty::hidapi
|
|
3rdparty::libusb
|
|
android
|
|
log
|
|
)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Profile-guided optimisation
|
|
# ---------------------------------------------------------------------------
|
|
#
|
|
# Scoped to rpcs3_emu and rpcsx-android deliberately, NOT to the whole build.
|
|
# 3rdparty is mostly LLVM, which is only hot while compiling guest code; adding
|
|
# instrumentation to it would multiply an already 1.2GB unstripped artifact for
|
|
# a payoff in compile speed rather than in frame time. What we measured as hot
|
|
# lives in these two: a simpleperf profile of the RSX thread during gameplay put
|
|
# 24.9% in vk::query_pool_manager::get_query_result, 9.4% in
|
|
# FIFO_control::fetch_u32_refill and the rest across the VK backend and the FIFO
|
|
# dispatch, all of which are rpcs3_emu.
|
|
#
|
|
# -DARMSX3_PGO=generate instrumented build, writes .profraw
|
|
# -DARMSX3_PGO=use -DARMSX3_PGO_PROFILE=<abs> optimised build against a profile
|
|
#
|
|
# Configure these into a SEPARATE build directory (BUILD_DIR=... android/configure.sh)
|
|
# so the instrumented objects never mix with the normal ones.
|
|
set(ARMSX3_PGO "off" CACHE STRING "Profile-guided optimisation: off, generate, or use")
|
|
set(ARMSX3_PGO_PROFILE "" CACHE FILEPATH "Merged .profdata, required when ARMSX3_PGO=use")
|
|
|
|
if(ARMSX3_PGO STREQUAL "generate")
|
|
# -fprofile-generate on BOTH compile and link: the link is what pulls in the
|
|
# profile runtime that writes the file.
|
|
foreach(pgo_target rpcs3_emu rpcsx-android)
|
|
target_compile_options(${pgo_target} PRIVATE -fprofile-generate)
|
|
target_link_options(${pgo_target} PRIVATE -fprofile-generate)
|
|
endforeach()
|
|
|
|
# Tells src/rpcsx-android.cpp to name the profile somewhere the app can
|
|
# actually write, and to flush it when the app goes to the background.
|
|
# Without that the runtime writes to the process CWD, which on Android is /
|
|
# and is not writable, so a whole play session produces nothing.
|
|
target_compile_definitions(rpcsx-android PRIVATE ARMSX3_PGO_GENERATE=1)
|
|
|
|
message(STATUS "ARMSX3: PGO instrumentation ON for rpcs3_emu and rpcsx-android")
|
|
elseif(ARMSX3_PGO STREQUAL "use")
|
|
if(NOT ARMSX3_PGO_PROFILE)
|
|
message(FATAL_ERROR "ARMSX3_PGO=use requires -DARMSX3_PGO_PROFILE=<absolute .profdata>")
|
|
endif()
|
|
if(NOT EXISTS "${ARMSX3_PGO_PROFILE}")
|
|
message(FATAL_ERROR "ARMSX3_PGO_PROFILE does not exist: ${ARMSX3_PGO_PROFILE}")
|
|
endif()
|
|
|
|
foreach(pgo_target rpcs3_emu rpcsx-android)
|
|
# Drift is tolerated rather than fatal: the profile ages the moment the
|
|
# code changes, and a warning per stale function would otherwise turn
|
|
# into thousands of errors under -Werror. Stale enough to matter shows up
|
|
# as a regression, which is why the profile gets regenerated rather than
|
|
# carried forward. A stale profile has actively pessimised this codebase's
|
|
# sibling project before, so treat age as a real risk, not a formality.
|
|
target_compile_options(${pgo_target} PRIVATE
|
|
-fprofile-use=${ARMSX3_PGO_PROFILE}
|
|
-Wno-error=profile-instr-out-of-date
|
|
-Wno-error=profile-instr-unprofiled
|
|
-Wno-profile-instr-out-of-date
|
|
-Wno-profile-instr-unprofiled)
|
|
endforeach()
|
|
|
|
message(STATUS "ARMSX3: PGO optimising against ${ARMSX3_PGO_PROFILE}")
|
|
endif()
|