Skip to content
This repository was archived by the owner on Sep 7, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ jobs:

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4
with:
validate-wrappers: false

- name: Install Android SDK components
run: |
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ build/

# Vendored snapshot of the upstream emulation core (populated by
# scripts/vendor_core.sh). The git submodule rpcs4/ remains the source of truth.
app/cpp/core/
app/cpp/Dependencies/
app/src/main/cpp/core/
app/src/main/cpp/Dependencies/

# Gradle wrapper downloads its distribution at first run
.gradle/
8 changes: 8 additions & 0 deletions app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON)

# Vulkan platform extension macros are required before any vulkan.h inclusion.
add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
add_definitions(-DVMA_STATIC_VULKAN_FUNCTIONS=0)
add_definitions(-DVMA_DYNAMIC_VULKAN_FUNCTIONS=0)
if(UNIX)
add_definitions(-D_GNU_SOURCE)
endif()
Expand Down Expand Up @@ -96,6 +98,7 @@ file(GLOB CORE_LOADERS_APP_SOURCES ${CORE_ROOT}/Loaders/App/*.cpp)
file(GLOB CORE_LOADERS_SFO_SOURCES ${CORE_ROOT}/Loaders/SFO/*.cpp)

file(GLOB CORE_OS_SOURCES ${CORE_ROOT}/OS/*.cpp)
file(GLOB CORE_PSN_SOURCES ${CORE_ROOT}/PSN/Providers/*/*.cpp)
file(GLOB LIBS_SUBDIRS RELATIVE ${CORE_ROOT}/OS/Libraries ${CORE_ROOT}/OS/Libraries/*)
set(LIB_SOURCES "")
foreach(lib ${LIBS_SUBDIRS})
Expand Down Expand Up @@ -131,6 +134,7 @@ set(ALL_CORE_SOURCES
${CORE_LOADERS_APP_SOURCES}
${CORE_LOADERS_SFO_SOURCES}
${CORE_OS_SOURCES}
${CORE_PSN_SOURCES}
${LIB_SOURCES}
${DEP_XXHASH_SOURCES}
${DEP_MINIZ_SOURCES}
Expand Down Expand Up @@ -170,6 +174,8 @@ set(UPSTREAM_INCLUDE_DIRS
${DEPS_DIR}/zydis/include
${DEPS_DIR}/zydis/src
${DEPS_DIR}/zydis/dependencies/zycore/include
${DEPS_DIR}/SDL/src/video/khronos
${DEPS_DIR}/SDL/src/video/khronos/vulkan
)

set(FILTERED_INCLUDE_DIRS "")
Expand Down Expand Up @@ -229,6 +235,8 @@ target_compile_options(rpcs4_core PRIVATE
-Wno-missing-field-initializers
-Wno-unused-variable
-Wno-sign-compare
-Wno-format-security
-include pthread_compat.h
# Upstream relies on heavy C++23 constructs; clang accepts them but can be
# noisy with deprecation notices from newer libc++.
-Wno-deprecated-declarations
Expand Down
15 changes: 15 additions & 0 deletions app/src/main/cpp/compat/SDL.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@

#include <cstdint>
#include <cstring>
#include <pthread.h>

#ifndef pthread_attr_getstackaddr
#define pthread_attr_getstackaddr(attr, addr) pthread_attr_getstack((attr), (addr), &(size_t){0})
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef uint8_t Uint8;
typedef int16_t Sint16;
typedef uint16_t Uint16;
typedef uint32_t Uint32;
typedef int32_t Sint32;
Expand Down Expand Up @@ -238,6 +244,8 @@ enum {
SDL_SCANCODE_UP = 82,
};

char* SDL_GetPrefPath(const char* org, const char* app);

const Uint8* SDL_GetKeyboardState(int* numkeys);

// ------------------------------------------- android integration entry points
Expand All @@ -254,6 +262,13 @@ bool Rpcs4Compat_HasAndroidWindow();
/** Cooperative stop: injects SDL_QUIT into the next event pump. */
void Rpcs4Compat_RequestQuit();

void Rpcs4Compat_SetPadState(
unsigned int sceButtonsMask,
float lx, float ly, float rx, float ry,
float l2, float r2);

void Rpcs4Compat_SetKeyboardKey(int scancode, bool down);

#ifdef __cplusplus
} // extern "C"
#endif
2 changes: 1 addition & 1 deletion app/src/main/cpp/compat/SDL_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void SDL_GameControllerClose(SDL_GameController* /*controller*/)

SDL_Joystick* SDL_GameControllerGetJoystick(SDL_GameController* controller)
{
return controller; // Opaque one-to-one handle.
return reinterpret_cast<SDL_Joystick*>(controller); // Opaque one-to-one handle.
}

Sint32 SDL_JoystickInstanceID(SDL_Joystick* /*joystick*/)
Expand Down
13 changes: 10 additions & 3 deletions app/src/main/cpp/compat/SDL_shim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@

namespace {

struct ShimWindow {
struct SDL_Window_Impl {
ANativeWindow* native_window = nullptr;
std::string title;
};

std::mutex g_window_mutex;
ANativeWindow* g_registered_window = nullptr; // set from JNI
ShimWindow g_created_window;
SDL_Window_Impl g_created_window;
std::atomic<bool> g_quit_requested { false };
std::string g_last_error = "no error";

Expand Down Expand Up @@ -113,7 +113,7 @@ SDL_Window* SDL_CreateWindow(

g_created_window.native_window = g_registered_window;
g_created_window.title = title ? title : "";
return &g_created_window;
return reinterpret_cast<SDL_Window*>(&g_created_window);
}

void SDL_SetWindowTitle(SDL_Window* /*window*/, const char* title)
Expand Down Expand Up @@ -231,6 +231,13 @@ SDL_bool SDL_Vulkan_CreateSurface(
return SDL_TRUE;
}

char* SDL_GetPrefPath(const char* /*org*/, const char* /*app*/)
{
static std::string pref_path;
pref_path = "/data/data/com.rpcs4.android/files/";
return const_cast<char*>(pref_path.c_str());
}

void SDL_Vulkan_GetDrawableSize(SDL_Window* window, int* w, int* h)
{
if (window == nullptr) return;
Expand Down
5 changes: 3 additions & 2 deletions app/src/main/cpp/compat/audio_aaudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,15 @@ void onStreamData(float* dst, int32_t numFrames)
o.pcm.erase(o.pcm.begin(), o.pcm.begin() + static_cast<long>(take));
}

void onDataCallback(AAudioStream* /*stream*/, void* userData, void* audioData, int32_t numFrames)
aaudio_data_callback_result_t onDataCallback(AAudioStream* /*stream*/, void* userData, void* audioData, int32_t numFrames)
{
auto* dst = static_cast<float*>(audioData);
(void)userData;
onStreamData(dst, numFrames);
return AAUDIO_CALLBACK_RESULT_CONTINUE;
}

void onErrorCallback(AAudioStream*, aaudio_result_t error)
void onErrorCallback(AAudioStream*, void* /*userData*/, aaudio_result_t error)
{
__android_log_print(ANDROID_LOG_ERROR, TAG, "AAudio error: %s", AAudio_convertResultToText(error));
}
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/cpp/compat/pthread_compat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once
#include <pthread.h>

#if defined(__ANDROID__)
inline int pthread_attr_getstackaddr(const pthread_attr_t* attr, void** stackaddr) {
size_t stacksize = 0;
return pthread_attr_getstack(attr, stackaddr, &stacksize);
}
#endif
84 changes: 84 additions & 0 deletions app/src/main/cpp/compat/vulkan/vk_platform.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//
// File: vk_platform.h
//
/*
** Copyright 2014-2024 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0
*/


#ifndef VK_PLATFORM_H_
#define VK_PLATFORM_H_

#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

/*
***************************************************************************************************
* Platform-specific directives and type declarations
***************************************************************************************************
*/

/* Platform-specific calling convention macros.
*
* Platforms should define these so that Vulkan clients call Vulkan commands
* with the same calling conventions that the Vulkan implementation expects.
*
* VKAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* VKAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* VKAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: VKAPI_ATTR void VKAPI_CALL vkCommand(void);
* Function pointer type: typedef void (VKAPI_PTR *PFN_vkCommand)(void);
*/
#if defined(_WIN32)
// On Windows, Vulkan commands use the stdcall convention
#define VKAPI_ATTR
#define VKAPI_CALL __stdcall
#define VKAPI_PTR VKAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "Vulkan is not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, Vulkan functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define VKAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define VKAPI_CALL
#define VKAPI_PTR VKAPI_ATTR
#else
// On other platforms, use the default calling convention
#define VKAPI_ATTR
#define VKAPI_CALL
#define VKAPI_PTR
#endif

#if !defined(VK_NO_STDDEF_H)
#include <stddef.h>
#endif // !defined(VK_NO_STDDEF_H)

#if !defined(VK_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined(VK_NO_STDINT_H)

#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

#endif
Loading
Loading