Better part 2?

This commit is contained in:
izzy2lost
2026-04-08 02:35:00 -04:00
parent 70aef9f9d3
commit fcfecd9ad2
9 changed files with 299 additions and 78 deletions
+1
View File
@@ -101,6 +101,7 @@ android {
"META-INF/LICENSE*",
"META-INF/NOTICE*"
)
/* Extract .so to disk (nativeLibraryDir); required for adrenotools hooks / custom GPU drivers. */
jniLibs.useLegacyPackaging = true
jniLibs.keepDebugSymbols += setOf("**/*.so")
}
+26 -1
View File
@@ -497,7 +497,6 @@ list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]gtk.*\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]sdl2.*\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]console-gl\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]console-vc\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]shader\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]vnc.*\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]xemu-snapshots\\.c$")
list(FILTER XEMU_CORE_SOURCES EXCLUDE REGEX "ui[\\\\/]xemu-thumbnail\\.cc$")
@@ -671,6 +670,30 @@ endif()
file(GLOB_RECURSE QAPI_GEN_SOURCES "${QAPI_GEN_DIR}/*.c")
list(APPEND XEMU_CORE_SOURCES ${QAPI_GEN_SOURCES})
# Generate GL shader headers used by ui/shader.c.
set(XEMU_SHADER_GEN_DIR "${CMAKE_BINARY_DIR}/ui/shader")
set(XEMU_SHADER_INPUTS
"${REPO_ROOT}/ui/shader/texture-blit.frag"
"${REPO_ROOT}/ui/shader/texture-blit.vert"
"${REPO_ROOT}/ui/shader/texture-blit-flip.vert"
)
file(MAKE_DIRECTORY "${XEMU_SHADER_GEN_DIR}")
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${XEMU_SHADER_INPUTS})
foreach(SHADER_INPUT ${XEMU_SHADER_INPUTS})
get_filename_component(SHADER_NAME "${SHADER_INPUT}" NAME)
string(REPLACE "." "-" SHADER_OUTPUT_BASENAME "${SHADER_NAME}")
set(SHADER_OUTPUT "${XEMU_SHADER_GEN_DIR}/${SHADER_OUTPUT_BASENAME}.h")
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" "${REPO_ROOT}/scripts/shaderinclude.py" "${SHADER_INPUT}"
OUTPUT_FILE "${SHADER_OUTPUT}"
WORKING_DIRECTORY "${REPO_ROOT}"
RESULT_VARIABLE SHADER_GEN_RESULT
)
if(NOT SHADER_GEN_RESULT EQUAL 0)
message(FATAL_ERROR "Shader header generation failed for ${SHADER_INPUT}")
endif()
endforeach()
# Generate block coroutine wrapper sources (block-gen.c).
set(BLOCK_GEN_C "${CMAKE_BINARY_DIR}/block-gen.c")
execute_process(
@@ -922,6 +945,8 @@ add_library(xemu SHARED
xemu_android.cpp
android_crash_handler.cpp
vmstate_if_android.c
xemu_fatx_import.c
xemu_hdd_tools_jni.c
)
target_compile_definitions(xemu PRIVATE ANDROID __ANDROID__ XBOX CONFIG_SDL CONFIG_OPENGL
@@ -9,7 +9,7 @@
#include <unwind.h>
namespace {
constexpr const char* kCrashTag = "hakuX";
constexpr const char* kCrashTag = "xemu-android";
constexpr size_t kPathMax = 512;
static char g_inline_aio_flag_path[kPathMax];
+8 -8
View File
@@ -11,14 +11,14 @@
#define CONFIG_AUDIO_DRIVERS "sdl",
#define CONFIG_DEVICES "config-devices.h"
#define CONFIG_QEMU_DATADIR "/sdcard/Android/data/com.rfandango.haku_x/files"
#define CONFIG_QEMU_FIRMWAREPATH "/sdcard/Android/data/com.rfandango.haku_x/files/firmware",
#define CONFIG_SYSCONFDIR "/sdcard/Android/data/com.rfandango.haku_x/files/etc"
#define CONFIG_QEMU_CONFDIR "/sdcard/Android/data/com.rfandango.haku_x/files/etc/xemu"
#define CONFIG_QEMU_HELPERDIR "/sdcard/Android/data/com.rfandango.haku_x/files/bin"
#define CONFIG_PREFIX "/sdcard/Android/data/com.rfandango.haku_x/files"
#define CONFIG_BINDIR "/sdcard/Android/data/com.rfandango.haku_x/files/bin"
#define CONFIG_QEMU_LOCALSTATEDIR "/sdcard/Android/data/com.rfandango.haku_x/files/state"
#define CONFIG_QEMU_DATADIR "/sdcard/Android/data/com.izzy2lost.x1box/files"
#define CONFIG_QEMU_FIRMWAREPATH "/sdcard/Android/data/com.izzy2lost.x1box/files/firmware",
#define CONFIG_SYSCONFDIR "/sdcard/Android/data/com.izzy2lost.x1box/files/etc"
#define CONFIG_QEMU_CONFDIR "/sdcard/Android/data/com.izzy2lost.x1box/files/etc/xemu"
#define CONFIG_QEMU_HELPERDIR "/sdcard/Android/data/com.izzy2lost.x1box/files/bin"
#define CONFIG_PREFIX "/sdcard/Android/data/com.izzy2lost.x1box/files"
#define CONFIG_BINDIR "/sdcard/Android/data/com.izzy2lost.x1box/files/bin"
#define CONFIG_QEMU_LOCALSTATEDIR "/sdcard/Android/data/com.izzy2lost.x1box/files/state"
#define CONFIG_BDRV_RW_WHITELIST
#define CONFIG_BDRV_RO_WHITELIST
@@ -152,6 +152,15 @@ int src_reset(SRC_STATE *state)
return 0;
}
SRC_STATE *src_delete(SRC_STATE *state)
{
if (state) {
free(state->input_buf);
free(state);
}
return NULL;
}
const char *src_strerror(int error)
{
(void)error;
+124 -59
View File
@@ -73,6 +73,8 @@ extern "C" bool nv2a_android_copy_readback(uint8_t **buffer, size_t *buffer_size
#include <volk.h>
static void* g_custom_vulkan_library = nullptr;
/* True only when a user-installed GPU driver ZIP was loaded (e.g. Turnip). */
static bool g_vulkan_custom_driver_zip_loaded = false;
extern "C" PFN_vkGetInstanceProcAddr xemu_android_get_vk_proc_addr(void)
{
@@ -82,12 +84,22 @@ extern "C" PFN_vkGetInstanceProcAddr xemu_android_get_vk_proc_addr(void)
return reinterpret_cast<PFN_vkGetInstanceProcAddr>(
dlsym(g_custom_vulkan_library, "vkGetInstanceProcAddr"));
}
extern "C" bool xemu_android_vulkan_custom_driver_zip_loaded(void)
{
return g_vulkan_custom_driver_zip_loaded;
}
#else
extern "C" bool xemu_android_vulkan_custom_driver_zip_loaded(void)
{
return false;
}
#endif
static int g_dvd_fd = -1;
namespace {
constexpr const char* kLogTag = "hakuX";
constexpr const char* kLogTag = "xemu-android";
constexpr const char* kPrefsName = "x1box_prefs";
static JNIEnv* GetEnv();
@@ -533,8 +545,9 @@ struct DisplaySettings {
bool vsync = false;
bool unlock_framerate = true;
bool validation_layers = false;
std::string renderer = "vulkan";
std::string filtering = "nearest";
std::string aspect_ratio = "auto";
std::string aspect_ratio = "fit";
};
static bool WriteConfigToml(const std::string& config_path,
@@ -581,7 +594,7 @@ static bool WriteConfigToml(const std::string& config_path,
}
general->insert_or_assign("show_welcome", false);
display->insert_or_assign("renderer", "vulkan");
display->insert_or_assign("renderer", ds.renderer);
display->insert_or_assign("filtering", ds.filtering);
display_window->insert_or_assign("vsync", ds.vsync);
@@ -780,67 +793,93 @@ static SetupFiles SyncSetupFiles() {
int tbSize = GetPrefInt(env, activity, "tcg_tb_size", 128);
DisplaySettings ds;
ds.surface_scale = GetPrefInt(env, activity, "surface_scale", 1);
ds.surface_scale = GetPrefInt(
env, activity, "setting_surface_scale",
GetPrefInt(env, activity, "surface_scale", 1));
if (ds.surface_scale < 1) ds.surface_scale = 1;
if (ds.surface_scale > 4) ds.surface_scale = 4;
ds.vsync = GetPrefBool(env, activity, "vsync", false);
ds.vsync = GetPrefBool(
env, activity, "setting_vsync",
GetPrefBool(env, activity, "vsync", false));
ds.unlock_framerate = GetPrefBool(env, activity, "unlock_framerate", true);
ds.validation_layers = GetPrefBool(env, activity, "validation_layers", false);
bool fp_safe = GetPrefBool(env, activity, "fp_safe", true);
xemu_set_fp_safe(fp_safe);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"FP safe (native arithmetic): %s", fp_safe ? "ON" : "OFF");
bool fp_jit = GetPrefBool(env, activity, "fp_jit", true);
xemu_set_fp_jit(fp_jit);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"FP JIT (native storage + inline ops): %s", fp_jit ? "ON" : "OFF");
bool fast_fences = GetPrefBool(env, activity, "fast_fences", false);
xemu_set_fast_fences(fast_fences);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"fast fences: %s", fast_fences ? "ON" : "OFF");
bool draw_reorder = GetPrefBool(env, activity, "draw_reorder", false);
xemu_set_draw_reorder(draw_reorder);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"draw reorder: %s", draw_reorder ? "ON" : "OFF");
bool draw_merge = GetPrefBool(env, activity, "draw_merge", false);
xemu_set_draw_merge(draw_merge);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"draw merge: %s", draw_merge ? "ON" : "OFF");
bool bindless_tex = GetPrefBool(env, activity, "bindless_textures", false);
xemu_set_bindless_textures(bindless_tex);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"bindless textures: %s", bindless_tex ? "ON" : "OFF");
bool async_compile = GetPrefBool(env, activity, "async_compile", false);
xemu_set_async_compile(async_compile);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"async compile: %s", async_compile ? "ON" : "OFF");
bool frame_skip = GetPrefBool(env, activity, "frame_skip", false);
xemu_set_frame_skip(frame_skip);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"frame skip: %s", frame_skip ? "ON" : "OFF");
int submit_frames = GetPrefInt(env, activity, "submit_frames", 2);
xemu_set_submit_frames(submit_frames);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"submit frames: %d", submit_frames);
int tier1_threshold = GetPrefInt(env, activity, "tier1_threshold", 64);
xemu_set_tier1_threshold(tier1_threshold);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"tier1 threshold: %d", tier1_threshold);
std::string filterPref = GetPrefString(env, activity, "filtering");
std::string rendererPref = GetPrefString(env, activity, "setting_renderer");
if (rendererPref.empty()) {
rendererPref = GetPrefString(env, activity, "renderer");
}
if (rendererPref == "opengl") {
ds.renderer = "opengl";
} else if (rendererPref == "vulkan") {
ds.renderer = "vulkan";
}
std::string filterPref = GetPrefString(env, activity, "setting_filtering");
if (filterPref.empty()) {
filterPref = GetPrefString(env, activity, "filtering");
}
if (!filterPref.empty()) ds.filtering = filterPref;
std::string arPref = GetPrefString(env, activity, "aspect_ratio");
if (!arPref.empty()) ds.aspect_ratio = arPref;
int displayMode = GetPrefInt(env, activity, "setting_display_mode", -1);
if (displayMode == 1) {
ds.aspect_ratio = "4:3";
} else if (displayMode == 2) {
ds.aspect_ratio = "16:9";
} else if (displayMode == 0) {
ds.aspect_ratio = "fit";
} else {
std::string arPref = GetPrefString(env, activity, "aspect_ratio");
if (!arPref.empty()) ds.aspect_ratio = arPref;
}
WriteConfigToml(out.config_path, out.mcpx, out.flash, out.hdd, out.dvd, out.eeprom, tbSize, ds);
LogInfoFmt("SyncSetupFiles: config %s", out.config_path.c_str());
@@ -857,7 +896,7 @@ static SetupFiles SyncSetupFiles() {
size_t n = fread(buf, 1, sizeof(buf) - 1, f);
buf[n] = '\0';
fclose(f);
__android_log_print(ANDROID_LOG_INFO, "hakuX-config",
__android_log_print(ANDROID_LOG_INFO, "xemu-config",
"--- xemu.toml ---\n%s\n--- end ---", buf);
}
}
@@ -913,7 +952,7 @@ static void xemu_pin_to_big_cores_cpp(const char *label) {
}
if (big_count > 0 && big_count < ncpus) {
if (syscall(__NR_sched_setaffinity, 0, sizeof(mask), &mask) == 0) {
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"%s: pinned to %d big cores (max_freq=%lu)",
label, big_count, max_freq);
}
@@ -959,7 +998,7 @@ extern "C" int xemu_android_main(int argc, char** argv) {
auto t_init_start = SDL_GetTicks();
qemu_init(argc, argv);
auto t_init_end = SDL_GetTicks();
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"qemu_init took %u ms", t_init_end - t_init_start);
/* qemu_init's cleanup_add_fd already closed the original fd */
@@ -992,7 +1031,7 @@ extern "C" int xemu_android_main(int argc, char** argv) {
* cache saved with different FP modes is automatically rejected. */
game_hash ^= (xemu_get_fp_safe() ? 0x1u : 0) | (xemu_get_fp_jit() ? 0x2u : 0);
int nhints = tb_cache_load(cache_path, game_hash);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"TB cache: loaded %d hints from %s", nhints, cache_path);
}
#endif
@@ -1047,7 +1086,7 @@ extern "C" int SDL_main(int argc, char* argv[]) {
auto t_sync_start = SDL_GetTicks();
SetupFiles setup = SyncSetupFiles();
auto t_sync_end = SDL_GetTicks();
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"SyncSetupFiles took %u ms", t_sync_end - t_sync_start);
xemu_android_set_inline_aio_crash_flag_path(setup.inline_aio_flag_path.empty()
@@ -1260,13 +1299,13 @@ extern "C" int SDL_main(int argc, char* argv[]) {
}
extern "C" JNIEXPORT jint JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeGetFps(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeGetFps(JNIEnv *, jobject)
{
return static_cast<jint>(g_nv2a_stats.increment_fps);
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeGetFramePacing(JNIEnv *env, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeGetFramePacing(JNIEnv *env, jobject)
{
char buf[256];
nv2a_profile_get_pacing_str(buf, sizeof(buf));
@@ -1274,7 +1313,7 @@ Java_com_rfandango_haku_1x_MainActivity_nativeGetFramePacing(JNIEnv *env, jobjec
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeGetShaderStats(JNIEnv *env, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeGetShaderStats(JNIEnv *env, jobject)
{
char buf[256];
nv2a_profile_get_shader_stats_str(buf, sizeof(buf));
@@ -1282,7 +1321,7 @@ Java_com_rfandango_haku_1x_MainActivity_nativeGetShaderStats(JNIEnv *env, jobjec
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeCaptureFrame(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeCaptureFrame(JNIEnv *, jobject)
{
#ifdef CONFIG_RENDERDOC
if (nv2a_dbg_renderdoc_available()) {
@@ -1294,7 +1333,7 @@ Java_com_rfandango_haku_1x_MainActivity_nativeCaptureFrame(JNIEnv *, jobject)
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeDumpDiagFrames(JNIEnv *, jobject, jint numFrames)
Java_com_izzy2lost_x1box_MainActivity_nativeDumpDiagFrames(JNIEnv *, jobject, jint numFrames)
{
nv2a_dbg_trigger_diag_frames((int)numFrames);
}
@@ -1302,19 +1341,19 @@ Java_com_rfandango_haku_1x_MainActivity_nativeDumpDiagFrames(JNIEnv *, jobject,
extern "C" char g_vulkan_driver_info[256];
extern "C" JNIEXPORT jstring JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeGetDriverInfo(JNIEnv *env, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeGetDriverInfo(JNIEnv *env, jobject)
{
return env->NewStringUTF(g_vulkan_driver_info);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetFpSafe(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetFpSafe(JNIEnv *, jobject)
{
return xemu_get_fp_safe() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetFpSafe(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetFpSafe(JNIEnv *, jobject, jboolean enable)
{
xemu_set_fp_safe(enable == JNI_TRUE);
const char *storage = SDL_AndroidGetInternalStoragePath();
@@ -1326,109 +1365,109 @@ Java_com_rfandango_haku_1x_SettingsActivity_nativeSetFpSafe(JNIEnv *, jobject, j
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetFastFences(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetFastFences(JNIEnv *, jobject)
{
return xemu_get_fast_fences() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetFastFences(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetFastFences(JNIEnv *, jobject, jboolean enable)
{
xemu_set_fast_fences(enable == JNI_TRUE);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetDrawReorder(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetDrawReorder(JNIEnv *, jobject)
{
return xemu_get_draw_reorder() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetDrawReorder(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetDrawReorder(JNIEnv *, jobject, jboolean enable)
{
xemu_set_draw_reorder(enable == JNI_TRUE);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetDrawMerge(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetDrawMerge(JNIEnv *, jobject)
{
return xemu_get_draw_merge() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetDrawMerge(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetDrawMerge(JNIEnv *, jobject, jboolean enable)
{
xemu_set_draw_merge(enable == JNI_TRUE);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetBindlessTextures(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetBindlessTextures(JNIEnv *, jobject)
{
return xemu_get_bindless_textures() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetBindlessTextures(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetBindlessTextures(JNIEnv *, jobject, jboolean enable)
{
xemu_set_bindless_textures(enable == JNI_TRUE);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetAsyncCompile(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetAsyncCompile(JNIEnv *, jobject)
{
return xemu_get_async_compile() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetAsyncCompile(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetAsyncCompile(JNIEnv *, jobject, jboolean enable)
{
xemu_set_async_compile(enable == JNI_TRUE);
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetFrameSkip(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetFrameSkip(JNIEnv *, jobject)
{
return xemu_get_frame_skip() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetFrameSkip(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetFrameSkip(JNIEnv *, jobject, jboolean enable)
{
xemu_set_frame_skip(enable == JNI_TRUE);
}
extern "C" JNIEXPORT jint JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetSubmitFrames(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetSubmitFrames(JNIEnv *, jobject)
{
return static_cast<jint>(xemu_get_submit_frames());
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetSubmitFrames(JNIEnv *, jobject, jint count)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetSubmitFrames(JNIEnv *, jobject, jint count)
{
xemu_set_submit_frames(static_cast<int>(count));
}
extern "C" JNIEXPORT jint JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetTier1Threshold(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetTier1Threshold(JNIEnv *, jobject)
{
return static_cast<jint>(xemu_get_tier1_threshold());
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetTier1Threshold(JNIEnv *, jobject, jint value)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetTier1Threshold(JNIEnv *, jobject, jint value)
{
xemu_set_tier1_threshold(static_cast<int>(value));
}
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeGetFpJit(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_SettingsActivity_nativeGetFpJit(JNIEnv *, jobject)
{
return xemu_get_fp_jit() ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_SettingsActivity_nativeSetFpJit(JNIEnv *, jobject, jboolean enable)
Java_com_izzy2lost_x1box_SettingsActivity_nativeSetFpJit(JNIEnv *, jobject, jboolean enable)
{
xemu_set_fp_jit(enable == JNI_TRUE);
const char *storage = SDL_AndroidGetInternalStoragePath();
@@ -1440,32 +1479,32 @@ Java_com_rfandango_haku_1x_SettingsActivity_nativeSetFpJit(JNIEnv *, jobject, jb
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativePauseEmulation(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativePauseEmulation(JNIEnv *, jobject)
{
xemu_android_pause_emulation();
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeResumeEmulation(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeResumeEmulation(JNIEnv *, jobject)
{
xemu_android_resume_emulation();
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_MainActivity_nativeExitEmulation(JNIEnv *, jobject)
Java_com_izzy2lost_x1box_MainActivity_nativeExitEmulation(JNIEnv *, jobject)
{
xemu_android_request_exit();
}
#ifdef CONFIG_VULKAN
extern "C" JNIEXPORT jboolean JNICALL
Java_com_rfandango_haku_1x_GpuDriverHelper_nativeSupportsCustomDriverLoading(JNIEnv *, jclass)
Java_com_izzy2lost_x1box_GpuDriverHelper_nativeSupportsCustomDriverLoading(JNIEnv *, jclass)
{
return access("/dev/kgsl-3d0", F_OK) == 0 ? JNI_TRUE : JNI_FALSE;
}
extern "C" JNIEXPORT void JNICALL
Java_com_rfandango_haku_1x_GpuDriverHelper_nativeInitializeDriver(
Java_com_izzy2lost_x1box_GpuDriverHelper_nativeInitializeDriver(
JNIEnv *env, jclass,
jstring hookLibDir, jstring customDriverDir,
jstring customDriverName)
@@ -1475,9 +1514,10 @@ Java_com_rfandango_haku_1x_GpuDriverHelper_nativeInitializeDriver(
const char *driver_name = customDriverName ? env->GetStringUTFChars(customDriverName, nullptr) : nullptr;
void *handle = nullptr;
g_vulkan_custom_driver_zip_loaded = false;
if (driver_name && driver_name[0] != '\0') {
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"Loading custom Vulkan driver: %s from %s",
driver_name, driver_dir ? driver_dir : "(null)");
handle = adrenotools_open_libvulkan(
@@ -1492,15 +1532,40 @@ Java_com_rfandango_haku_1x_GpuDriverHelper_nativeInitializeDriver(
if (handle) {
g_custom_vulkan_library = handle;
__android_log_print(ANDROID_LOG_INFO, "hakuX",
g_vulkan_custom_driver_zip_loaded = true;
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"Custom Vulkan driver loaded successfully via adrenotools");
} else {
__android_log_print(ANDROID_LOG_WARN, "hakuX",
__android_log_print(ANDROID_LOG_WARN, "xemu-android",
"adrenotools failed to load custom driver, will fall back to system default");
}
} else {
__android_log_print(ANDROID_LOG_INFO, "hakuX",
"No custom driver specified, using system Vulkan driver");
/*
* No Turnip/custom ZIP: still dlopen libvulkan through adrenotools with
* featureFlags=0 (stock driver). That matches the volk dispatch path used
* when a custom .so is loaded and applies adrenotools hooks from
* nativeLibraryDir — avoiding OEM-specific quirks from mixing linker-
* resolved Vulkan symbols with this code path.
*/
if (hook_dir && hook_dir[0] != '\0') {
handle = adrenotools_open_libvulkan(
RTLD_NOW,
0,
(driver_dir && driver_dir[0] != '\0') ? driver_dir : nullptr,
hook_dir,
nullptr,
nullptr,
nullptr,
nullptr);
}
if (handle) {
g_custom_vulkan_library = handle;
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"System Vulkan driver opened via adrenotools (hooked dispatch)");
} else {
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"Vulkan: default linkage (adrenotools system open not used)");
}
}
if (driver_name) env->ReleaseStringUTFChars(customDriverName, driver_name);
@@ -169,7 +169,7 @@ const char *xemu_settings_get_base_path(void)
}
base_path = base ? strdup(base) : strdup("");
SDL_free(base);
__android_log_print(ANDROID_LOG_INFO, "hakuX-config",
__android_log_print(ANDROID_LOG_INFO, "xemu-config",
"xemu_settings_get_base_path: %s", base_path);
return base_path;
}
@@ -245,7 +245,7 @@ bool xemu_settings_load(void)
parsed == CONFIG_DISPLAY_RENDERER_OPENGL) {
g_config.display.renderer = parsed;
}
__android_log_print(ANDROID_LOG_INFO, "hakuX",
__android_log_print(ANDROID_LOG_INFO, "xemu-android",
"Config display.renderer=%s (using %s)",
renderer->c_str(),
g_config.display.renderer == CONFIG_DISPLAY_RENDERER_VULKAN
@@ -346,7 +346,7 @@ bool xemu_settings_load(void)
if (*tcg_thread == "single" || *tcg_thread == "multi") {
setenv("XEMU_ANDROID_TCG_THREAD", tcg_thread->c_str(), 1);
} else {
__android_log_print(ANDROID_LOG_WARN, "hakuX",
__android_log_print(ANDROID_LOG_WARN, "xemu-android",
"Ignoring android.tcg_thread=%s (expected single|multi)",
tcg_thread->c_str());
}
@@ -508,7 +508,7 @@ bool xemu_settings_load_gamepad_mapping(const char *guid,
GamepadMappings *new_mappings = static_cast<GamepadMappings *>(realloc(
g_config.input.gamepad_mappings, sizeof(GamepadMappings) * new_count));
if (!new_mappings) {
__android_log_print(ANDROID_LOG_ERROR, "hakuX",
__android_log_print(ANDROID_LOG_ERROR, "xemu-android",
"Failed to allocate gamepad mapping for %s", guid);
return false;
}
+104 -2
View File
@@ -1,15 +1,50 @@
#include <jni.h>
#include <android/log.h>
#include <array>
#include <string>
#define XISO_LOG_TAG "XisoConverter"
extern "C" int xiso_convert_iso_to_xiso(const char *input_path,
const char *output_path,
char *err_buf,
size_t err_buf_len);
extern "C" int xiso_convert_iso_to_xiso_with_progress(
const char *input_path,
const char *output_path,
char *err_buf,
size_t err_buf_len,
void (*progress_callback)(int current, int total, void *user_data),
void *user_data);
struct JniProgressContext {
JNIEnv *env;
jobject callback;
jmethodID method_id;
bool failed;
};
static void xiso_progress_bridge(int current, int total, void *user_data) {
auto *ctx = static_cast<JniProgressContext *>(user_data);
if (ctx->failed) return;
if (ctx->env->ExceptionCheck()) {
ctx->failed = true;
ctx->env->ExceptionClear();
return;
}
ctx->env->CallVoidMethod(ctx->callback, ctx->method_id,
static_cast<jint>(current),
static_cast<jint>(total));
if (ctx->env->ExceptionCheck()) {
ctx->failed = true;
ctx->env->ExceptionClear();
}
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_rfandango_haku_1x_XisoConverterNative_nativeConvertIsoToXiso(
Java_com_izzy2lost_x1box_XisoConverterNative_nativeConvertIsoToXiso(
JNIEnv *env,
jclass,
jstring input_path,
@@ -45,5 +80,72 @@ Java_com_rfandango_haku_1x_XisoConverterNative_nativeConvertIsoToXiso(
const char *msg = error_buffer[0] != '\0'
? error_buffer.data()
: "ISO conversion failed";
__android_log_print(ANDROID_LOG_ERROR, XISO_LOG_TAG,
"nativeConvertIsoToXiso rc=%d: %s", rc, msg);
return env->NewStringUTF(msg);
}
}
extern "C" JNIEXPORT jstring JNICALL
Java_com_izzy2lost_x1box_XisoConverterNative_nativeConvertIsoToXisoWithProgress(
JNIEnv *env,
jclass,
jstring input_path,
jstring output_path,
jobject progress_callback) {
if (input_path == nullptr || output_path == nullptr) {
return env->NewStringUTF("Input/output path is missing");
}
const char *input_chars = env->GetStringUTFChars(input_path, nullptr);
if (input_chars == nullptr) {
return env->NewStringUTF("Failed to read input path");
}
const char *output_chars = env->GetStringUTFChars(output_path, nullptr);
if (output_chars == nullptr) {
env->ReleaseStringUTFChars(input_path, input_chars);
return env->NewStringUTF("Failed to read output path");
}
std::array<char, 4096> error_buffer{};
int rc;
if (progress_callback != nullptr) {
jclass cb_class = env->GetObjectClass(progress_callback);
jmethodID on_progress = env->GetMethodID(cb_class, "onProgress", "(II)V");
if (on_progress == nullptr) {
env->ReleaseStringUTFChars(input_path, input_chars);
env->ReleaseStringUTFChars(output_path, output_chars);
return env->NewStringUTF("Failed to find onProgress method on callback");
}
JniProgressContext ctx{env, progress_callback, on_progress, false};
rc = xiso_convert_iso_to_xiso_with_progress(
input_chars,
output_chars,
error_buffer.data(),
error_buffer.size(),
xiso_progress_bridge,
&ctx);
} else {
rc = xiso_convert_iso_to_xiso(
input_chars,
output_chars,
error_buffer.data(),
error_buffer.size());
}
env->ReleaseStringUTFChars(input_path, input_chars);
env->ReleaseStringUTFChars(output_path, output_chars);
if (rc == 0) {
return nullptr;
}
const char *msg = error_buffer[0] != '\0'
? error_buffer.data()
: "ISO conversion failed";
__android_log_print(ANDROID_LOG_ERROR, XISO_LOG_TAG,
"nativeConvertIsoToXisoWithProgress rc=%d: %s", rc, msg);
return env->NewStringUTF(msg);
}
+22 -3
View File
@@ -482,9 +482,28 @@ static void add_optional_device_extension_names(
}
#if OPT_DYNAMIC_BLEND
r->eds3_blend_supported = add_extension_if_available(
available_extensions, enabled_extension_names,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
/*
* Stock Qualcomm drivers often advertise EXT_extended_dynamic_state3 but
* crash or fault inside vkCmdSetColorBlend* / related dynamic state during
* real draws. Turnip and other updaters are fine; skip EDS3 on Adreno-only
* Android so we use static pipeline blend state instead.
*/
# ifdef __ANDROID__
extern bool xemu_android_vulkan_custom_driver_zip_loaded(void);
if (r->device_props.vendorID == 0x5143u &&
!xemu_android_vulkan_custom_driver_zip_loaded()) {
r->eds3_blend_supported = false;
fprintf(stderr, "Qualcomm GPU: omitting %s (use static blend for stock-driver compatibility)\n",
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
__android_log_print(ANDROID_LOG_INFO, "hakuX",
"Qualcomm stock driver: dynamic blend (EDS3) disabled");
} else
# endif
{
r->eds3_blend_supported = add_extension_if_available(
available_extensions, enabled_extension_names,
VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME);
}
#endif
#if OPT_BINDLESS_TEXTURES