Initial commit: multi-platform emulator with PS1 support
Jetpack Compose app with adaptive layouts (phone/tablet/foldable) using Window Size Classes. Integrates a C++ libretro frontend via JNI for actual PS1 emulation using pcsx_rearmed, with AAudio output and ANativeWindow rendering. - Emulation core architecture with interface for NES, SNES, N64, Genesis, PS1, PS2 (PS1 implemented, others placeholder) - Touch controller overlay with D-pad (diagonal support), face buttons, shoulders, and analog sticks - Bluetooth/USB controller detection and input mapping - Customizable controller layout editor with drag-to-reposition - Game library with auto-scan of /sdcard/Games/ subfolders - Auto-import of libretro core .so from /sdcard/Games/cores/ - Save states and SRAM persistence
This commit is contained in:
119
app/src/main/cpp/jni_bridge.cpp
Normal file
119
app/src/main/cpp/jni_bridge.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include "libretro_frontend.h"
|
||||
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
#define LOG_TAG "JniBridge"
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeLoadCore(JNIEnv* env, jobject, jstring corePath) {
|
||||
const char* path = env->GetStringUTFChars(corePath, nullptr);
|
||||
bool result = LibretroFrontend::instance().loadCore(path);
|
||||
env->ReleaseStringUTFChars(corePath, path);
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeLoadGame(JNIEnv* env, jobject, jstring romPath) {
|
||||
const char* path = env->GetStringUTFChars(romPath, nullptr);
|
||||
bool result = LibretroFrontend::instance().loadGame(path);
|
||||
env->ReleaseStringUTFChars(romPath, path);
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeStart(JNIEnv*, jobject) {
|
||||
LibretroFrontend::instance().start();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativePause(JNIEnv*, jobject) {
|
||||
LibretroFrontend::instance().pause();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeResume(JNIEnv*, jobject) {
|
||||
LibretroFrontend::instance().resume();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeStop(JNIEnv*, jobject) {
|
||||
LibretroFrontend::instance().stop();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeReset(JNIEnv*, jobject) {
|
||||
LibretroFrontend::instance().reset();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetSurface(JNIEnv* env, jobject, jobject surface) {
|
||||
if (surface) {
|
||||
ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
|
||||
LibretroFrontend::instance().setWindow(window);
|
||||
ANativeWindow_release(window); // setWindow does its own acquire
|
||||
} else {
|
||||
LibretroFrontend::instance().releaseWindow();
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeReleaseSurface(JNIEnv*, jobject) {
|
||||
LibretroFrontend::instance().releaseWindow();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetButtonState(JNIEnv*, jobject, jint state) {
|
||||
LibretroFrontend::instance().setButtonState(static_cast<uint16_t>(state));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetAnalogState(JNIEnv*, jobject, jint stick, jshort x, jshort y) {
|
||||
LibretroFrontend::instance().setAnalogState(stick, x, y);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSaveState(JNIEnv* env, jobject, jstring path) {
|
||||
const char* p = env->GetStringUTFChars(path, nullptr);
|
||||
bool result = LibretroFrontend::instance().saveState(p);
|
||||
env->ReleaseStringUTFChars(path, p);
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeLoadState(JNIEnv* env, jobject, jstring path) {
|
||||
const char* p = env->GetStringUTFChars(path, nullptr);
|
||||
bool result = LibretroFrontend::instance().loadState(p);
|
||||
env->ReleaseStringUTFChars(path, p);
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetAudioEnabled(JNIEnv*, jobject, jboolean enabled) {
|
||||
LibretroFrontend::instance().setAudioEnabled(enabled);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetFrameSkip(JNIEnv*, jobject, jint skip) {
|
||||
LibretroFrontend::instance().setFrameSkip(skip);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetSystemDir(JNIEnv* env, jobject, jstring dir) {
|
||||
const char* d = env->GetStringUTFChars(dir, nullptr);
|
||||
LibretroFrontend::instance().setSystemDir(d);
|
||||
env->ReleaseStringUTFChars(dir, d);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_lazy_emulate_emulation_NativeLibretro_nativeSetSaveDir(JNIEnv* env, jobject, jstring dir) {
|
||||
const char* d = env->GetStringUTFChars(dir, nullptr);
|
||||
LibretroFrontend::instance().setSaveDir(d);
|
||||
env->ReleaseStringUTFChars(dir, d);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
Reference in New Issue
Block a user