Share This
Связаться со мной
Крути в низ
Categories
//Эмулятор PS2 на Android — ёжик плакал и кололся, но продолжал есть кактус

Эмулятор PS2 на Android — ёжик плакал и кололся, но продолжал есть кактус

05.10.2020Category : My Habr

Привет всем читателям!

Я продолжаю тему программного эмулятора для PlayStation 1, PlayStation 2 и PlayStation Portable — Omega Red. Более подробно:

  • Редизайн пользовательского интерфейса эмулятора Omega Red (Вторая серия)
  • Редизайн пользовательского интерфейса эмулятора Omega Red
  • 4К (2160р) разрешение для игр PS1, PS2, PSP в эмуляторе Omega Red
  • Видео гид по эмулятору Omega Red
  • Поддержка геймпада для эмулятора Omega Red
  • Новый PS1 графический рендерер для эмулятора Omega Red
  • Omega Red + PS1 эмулятор = Кодзима гений
  • PS2/PSP эмулятор + game play streaming (YouTube, Facebook, Twitch) = новая версия Omega Red
  • PS2/PSP эмулятор + Google Drive + YouTube = «безумие» продолжается
  • Как я подружил PlayStation 2 и PlayStation Portable (спойлер — объединил в один эмулятор)
  • Красный Омега PS2 эмулятор

Данную новость я написал в связи с решением портировать часть кода разрабатываемого мной эмулятора на Android — ARM64 платформу. Поспешу предупредить, что скачать и запустить не получиться — проект только на начальной стадии развития. Однако, для тех читателей, кто не лишён профессионального любопытства — добро пожаловать под кат.

P.S. Новая версия эмулятора для Windows OS (с поддержкой гемпадов по старому протоколу — DirectInput8) доступна по ссылке: Omega Red

Для любопытствующих — проект был инициирован больше года назад и мой интерес к нему возгарался и затухал циклически. Но лишь недавно мне удалось закончить первый этап — добиться корректной компиляции и линковки кода.

Основой портирования я решил взять центральное ядро эмулятора PCSX2, переписанное мной в форме отдельной динамически загружаемой библиотеки (подробно «Красный Омега PS2 эмулятор»). Стартовая версия библиотеки была написана для Windows OS на Microsoft Visual Studio — как результат, существует объективная проблема в совместимости сред разработки-компиляции и совместимости сред выполнения кода библиотек. Длительная работа с библиотекой ядра эмулятора позволила разработать паттерн алгоритма внешнего исполняемого кода по отношению библиотеке через разработанный API.

Первой задачей было написание кода для этого алгоритма на Java для Android. Программный код достаточно сложен по причине наличия большого количества функций «обратного» вызова — библиотека ядра эмулятора включает три программных потока исполнения кода и они потребуют данных для обработки — БИОСа, данных геймпадов, загрузки плагинов. В коде для Windows OS на WPF C# задача реализации «обратного» вызова проста через встроенный механизм маршалинга данных. Но для Java виртуальной машины маршалинг данных из нативного кода С++ в виртуальную машину и обратно становиться крупной проблемой. Для этого я определил отдельный С++ файл AndroidInterface.cpp в PCSX2Lib с определением Java Native интерфейсов в следующем виде:

extern "C" JNIEXPORT void JNICALL Java_com_xirexel_omegared_PCSX2_PCSX2LibNative_NativeSetElfPathFunc(JNIEnv *env, jobject instance, jstring a_config_) { const char *a_config = env->GetStringUTFChars(a_config_, 0); PCSX2_Hle_SetElfPathFunc(a_config); env->ReleaseStringUTFChars(a_config_, a_config); }

Загрузка нативного кода происходит стандартным образом:

public final class PCSX2LibNative { static { System.loadLibrary("PCSX2Lib"); }

Вызов Java методов из С++ кода имеет следующий вид:

static void callOnePtrTwoIntBoolean(const std::string& aMethodCallback, unsigned char* arg1, int arg2, int arg3, bool arg4) { if(s_JavaVM == nullptr) return; JNIEnv* l_Env = nullptr; const jint get_res = s_JavaVM->GetEnv(reinterpret_cast<void**>(&l_Env), JNI_VERSION_1_6); if (get_res == JNI_EDETACHED) { if (s_JavaVM->AttachCurrentThread(&l_Env, NULL) != 0) { return; } } else if (get_res != JNI_OK) { return; } jclass l_PCSX2LibNative = l_Env->GetObjectClass(g_PCSX2LibNative); jmethodID methodId=l_Env->GetMethodID(l_PCSX2LibNative, aMethodCallback.data(), "(Ljava/nio/ByteBuffer;IZ)V"); jobject l_buffer = l_Env->NewDirectByteBuffer(arg1, arg3); l_Env->CallVoidMethod(g_PCSX2LibNative, methodId, l_buffer, arg2, arg4); }

Второй задачей было создание CMake скрипта для корректной компиляции нативного кода для Android проекта. Получилось следующее:

# For more information about using CMake with Android Studio, read the # documentation: https://d.android.com/studio/projects/add-native-code.html # Sets the minimum version of CMake required to build the native library. cmake_minimum_required(VERSION 3.4.1) set (EXTEND_DIR ${CMAKE_CURRENT_SOURCE_DIR}/Extend) set (PCSX2LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../PCSX2Lib) set (PCSX2_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../../pcsx2) set (FRAMEWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Common/Framework) set (UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Common/Utilities) set (MEMORYMANAGER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Common/MemoryManager) set (PUGIXML_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Common/PugiXML) set (FRAMEWORK_UTILITIES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Common/Framework/Utilities) set (PCSX2_UTILITIES_SRC_DIR ${PCSX2_DIR}/../common/src/Utilities) set (PTHREADS_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Common/pthreads4w/include) set (LIBAIO_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libaio/src) set (MODULES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../Modules) add_definitions(-DDISABLE_RECORDING -DPUGIXML_WCHAR_MODE) if(${ANDROID_ABI} STREQUAL "x86") add_definitions(-DANDROID_ABI_X86) endif() if( (${ANDROID_ABI} STREQUAL "x86") ) message(ANDROID_ABI = ${ANDROID_ABI}) set(SVU_ZEROREC_SRC ${CMAKE_CURRENT_SOURCE_DIR}/CPU/x86/aVUzerorec.S ) add_subdirectory(libaio) add_subdirectory(Framework) add_subdirectory(Utilities) add_subdirectory(Emitters) add_subdirectory(MemoryManager) add_subdirectory(PugiXML) add_subdirectory(PCSX2Lib) add_subdirectory(Modules) add_subdirectory(BiosControl) endif()

Полагаю что читатели сразу поняли причину, почему проект невозможно загрузить на смартфон — нативный код компилируется только для процессоров х86 архитектуры.

В настоящий момент проект бесполезен почти полностью — но только почти. Текущий результат показал следующее:

1. разработка отдельной библиотеки нативного кода для PCSX2 эмулятора было правильным решением, упростившем портирование на другую платформу;

2. корректная компиляция и линковка кода указывает на совместимость кода PCSX2 эмулятора с библиотеками компиляции Android NDK.

Как очевидно, в настоящий момент проблемой является написание кода для ARM64 процессоров — проблема объективно сложная, но на мой взгляд решаемая. Для любителей повозиться с кодом — проект для среды разработки Android Studio доступен на GitHub: AndroidStudio.

В настоящий момент Windows OS версия программы доступна по ссылке: Omega Red и представлена на GitHub: OmegaRed.

emuljator ps2 na android jozhik plakal i kololsja no prodolzhal est kaktus c5c87f6 - Эмулятор PS2 на Android — ёжик плакал и кололся, но продолжал есть кактус

  • 12 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close