mirror of
https://github.com/rafaelvcaetano/melonDS-android.git
synced 2024-11-27 07:30:40 +00:00
Setup native interface on app launch
This will allow different entry points to use a common configuration, avoiding duplicate setup logic
This commit is contained in:
parent
ee7bafb4ae
commit
d69a4e7bdf
@ -40,6 +40,8 @@ add_library(
|
||||
SHARED
|
||||
|
||||
src/main/cpp/MelonDSAndroidJNI.cpp
|
||||
src/main/cpp/MelonDSAndroidConfiguration.cpp
|
||||
src/main/cpp/MelonDSAndroidInterface.cpp
|
||||
src/main/cpp/UriFileHandler.cpp
|
||||
src/main/cpp/JniEnvHandler.cpp
|
||||
)
|
||||
|
192
app/src/main/cpp/MelonDSAndroidConfiguration.cpp
Normal file
192
app/src/main/cpp/MelonDSAndroidConfiguration.cpp
Normal file
@ -0,0 +1,192 @@
|
||||
#include <jni.h>
|
||||
#include "MelonDS.h"
|
||||
#include "MelonDSAndroidConfiguration.h"
|
||||
|
||||
MelonDSAndroid::EmulatorConfiguration MelonDSAndroidConfiguration::buildEmulatorConfiguration(JNIEnv* env, jobject emulatorConfiguration) {
|
||||
jclass emulatorConfigurationClass = env->GetObjectClass(emulatorConfiguration);
|
||||
jclass uriClass = env->FindClass("android/net/Uri");
|
||||
jclass consoleTypeEnumClass = env->FindClass("me/magnum/melonds/domain/model/ConsoleType");
|
||||
jclass audioBitrateEnumClass = env->FindClass("me/magnum/melonds/domain/model/AudioBitrate");
|
||||
jclass audioInterpolationEnumClass = env->FindClass("me/magnum/melonds/domain/model/AudioInterpolation");
|
||||
jclass audioLatencyEnumClass = env->FindClass("me/magnum/melonds/domain/model/AudioLatency");
|
||||
jclass micSourceEnumClass = env->FindClass("me/magnum/melonds/domain/model/MicSource");
|
||||
|
||||
jmethodID uriToStringMethod = env->GetMethodID(uriClass, "toString", "()Ljava/lang/String;");
|
||||
|
||||
jboolean useCustomBios = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "useCustomBios", "Z"));
|
||||
jobject dsBios7Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsBios7Uri", "Landroid/net/Uri;"));
|
||||
jobject dsBios9Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsBios9Uri", "Landroid/net/Uri;"));
|
||||
jobject dsFirmwareUri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsFirmwareUri", "Landroid/net/Uri;"));
|
||||
jobject dsiBios7Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiBios7Uri", "Landroid/net/Uri;"));
|
||||
jobject dsiBios9Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiBios9Uri", "Landroid/net/Uri;"));
|
||||
jobject dsiFirmwareUri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiFirmwareUri", "Landroid/net/Uri;"));
|
||||
jobject dsiNandUri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiNandUri", "Landroid/net/Uri;"));
|
||||
jstring internalFilesDir = (jstring) env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "internalDirectory", "Ljava/lang/String;"));
|
||||
jfloat fastForwardMaxSpeed = env->GetFloatField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "fastForwardSpeedMultiplier", "F"));
|
||||
jboolean enableRewind = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rewindEnabled", "Z"));
|
||||
jint rewindPeriodSeconds = env->GetIntField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rewindPeriodSeconds", "I"));
|
||||
jint rewindWindowSeconds = env->GetIntField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rewindWindowSeconds", "I"));
|
||||
jboolean useJit = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "useJit", "Z"));
|
||||
jobject consoleTypeEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "consoleType", "Lme/magnum/melonds/domain/model/ConsoleType;"));
|
||||
jint consoleType = env->GetIntField(consoleTypeEnum, env->GetFieldID(consoleTypeEnumClass, "consoleType", "I"));
|
||||
jboolean soundEnabled = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "soundEnabled", "Z"));
|
||||
jint volume = env->GetIntField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "volume", "I"));
|
||||
jobject audioInterpolationEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "audioInterpolation", "Lme/magnum/melonds/domain/model/AudioInterpolation;"));
|
||||
jint audioInterpolation = env->GetIntField(audioInterpolationEnum, env->GetFieldID(audioInterpolationEnumClass, "interpolationValue", "I"));
|
||||
jobject audioBitrateEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "audioBitrate", "Lme/magnum/melonds/domain/model/AudioBitrate;"));
|
||||
jint audioBitrate = env->GetIntField(audioBitrateEnum, env->GetFieldID(audioBitrateEnumClass, "bitrateValue", "I"));
|
||||
jobject audioLatencyEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "audioLatency", "Lme/magnum/melonds/domain/model/AudioLatency;"));
|
||||
jint audioLatency = env->GetIntField(audioLatencyEnum, env->GetFieldID(audioLatencyEnumClass, "latencyValue", "I"));
|
||||
jobject micSourceEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "micSource", "Lme/magnum/melonds/domain/model/MicSource;"));
|
||||
jint micSource = env->GetIntField(micSourceEnum, env->GetFieldID(micSourceEnumClass, "sourceValue", "I"));
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
jstring dsBios7String = dsBios7Uri ? (jstring) env->CallObjectMethod(dsBios7Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsBios9String = dsBios9Uri ? (jstring) env->CallObjectMethod(dsBios9Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsFirmwareString = dsFirmwareUri ? (jstring) env->CallObjectMethod(dsFirmwareUri, uriToStringMethod) : nullptr;
|
||||
jstring dsiBios7String = dsiBios7Uri ? (jstring) env->CallObjectMethod(dsiBios7Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsiBios9String = dsiBios9Uri ? (jstring) env->CallObjectMethod(dsiBios9Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsiFirmwareString = dsiFirmwareUri ? (jstring) env->CallObjectMethod(dsiFirmwareUri, uriToStringMethod) : nullptr;
|
||||
jstring dsiNandString = dsiNandUri ? (jstring) env->CallObjectMethod(dsiNandUri, uriToStringMethod) : nullptr;
|
||||
const char* dsBios7Path = dsBios7Uri ? env->GetStringUTFChars(dsBios7String, &isCopy) : nullptr;
|
||||
const char* dsBios9Path = dsBios9Uri ? env->GetStringUTFChars(dsBios9String, &isCopy) : nullptr;
|
||||
const char* dsFirmwarePath = dsFirmwareUri ? env->GetStringUTFChars(dsFirmwareString, &isCopy) : nullptr;
|
||||
const char* dsiBios7Path = dsiBios7Uri ? env->GetStringUTFChars(dsiBios7String, &isCopy) : nullptr;
|
||||
const char* dsiBios9Path = dsiBios9Uri ? env->GetStringUTFChars(dsiBios9String, &isCopy) : nullptr;
|
||||
const char* dsiFirmwarePath = dsiFirmwareUri ? env->GetStringUTFChars(dsiFirmwareString, &isCopy) : nullptr;
|
||||
const char* dsiNandPath = dsiNandUri ? env->GetStringUTFChars(dsiNandString, &isCopy) : nullptr;
|
||||
const char* internalDir = env->GetStringUTFChars(internalFilesDir, nullptr);
|
||||
jobject firmwareConfigurationObject = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "firmwareConfiguration", "Lme/magnum/melonds/domain/model/FirmwareConfiguration;"));
|
||||
jobject rendererConfigurationObject = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rendererConfiguration", "Lme/magnum/melonds/domain/model/RendererConfiguration;"));
|
||||
|
||||
MelonDSAndroid::EmulatorConfiguration finalEmulatorConfiguration;
|
||||
finalEmulatorConfiguration.userInternalFirmwareAndBios = !useCustomBios;
|
||||
finalEmulatorConfiguration.dsBios7Path = const_cast<char*>(dsBios7Path);
|
||||
finalEmulatorConfiguration.dsBios9Path = const_cast<char*>(dsBios9Path);
|
||||
finalEmulatorConfiguration.dsFirmwarePath = const_cast<char*>(dsFirmwarePath);
|
||||
finalEmulatorConfiguration.dsiBios7Path = const_cast<char*>(dsiBios7Path);
|
||||
finalEmulatorConfiguration.dsiBios9Path = const_cast<char*>(dsiBios9Path);
|
||||
finalEmulatorConfiguration.dsiFirmwarePath = const_cast<char*>(dsiFirmwarePath);
|
||||
finalEmulatorConfiguration.dsiNandPath = const_cast<char*>(dsiNandPath);
|
||||
finalEmulatorConfiguration.internalFilesDir = const_cast<char*>(internalDir);
|
||||
finalEmulatorConfiguration.fastForwardSpeedMultiplier = fastForwardMaxSpeed;
|
||||
finalEmulatorConfiguration.useJit = useJit;
|
||||
finalEmulatorConfiguration.consoleType = consoleType;
|
||||
finalEmulatorConfiguration.soundEnabled = soundEnabled;
|
||||
finalEmulatorConfiguration.volume = volume;
|
||||
finalEmulatorConfiguration.audioInterpolation = audioInterpolation;
|
||||
finalEmulatorConfiguration.audioBitrate = audioBitrate;
|
||||
finalEmulatorConfiguration.audioLatency = audioLatency;
|
||||
finalEmulatorConfiguration.micSource = micSource;
|
||||
finalEmulatorConfiguration.firmwareConfiguration = buildFirmwareConfiguration(env, firmwareConfigurationObject);
|
||||
finalEmulatorConfiguration.renderSettings = buildRenderSettings(env, rendererConfigurationObject);
|
||||
finalEmulatorConfiguration.rewindEnabled = enableRewind ? 1 : 0;
|
||||
finalEmulatorConfiguration.rewindCaptureSpacingSeconds = rewindPeriodSeconds;
|
||||
finalEmulatorConfiguration.rewindLengthSeconds = rewindWindowSeconds;
|
||||
return finalEmulatorConfiguration;
|
||||
}
|
||||
|
||||
MelonDSAndroid::FirmwareConfiguration MelonDSAndroidConfiguration::buildFirmwareConfiguration(JNIEnv* env, jobject firmwareConfiguration) {
|
||||
jclass firmwareConfigurationClass = env->GetObjectClass(firmwareConfiguration);
|
||||
jstring nicknameString = (jstring) env->GetObjectField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "nickname", "Ljava/lang/String;"));
|
||||
jstring messageString = (jstring) env->GetObjectField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "message", "Ljava/lang/String;"));
|
||||
int language = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "language", "I"));
|
||||
int colour = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "favouriteColour", "I"));
|
||||
int birthdayDay = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "birthdayDay", "I"));
|
||||
int birthdayMonth = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "birthdayMonth", "I"));
|
||||
bool randomizeMacAddress = env->GetBooleanField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "randomizeMacAddress", "Z"));
|
||||
jstring macAddressString = (jstring) env->GetObjectField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "internalMacAddress", "Ljava/lang/String;"));
|
||||
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
const char* nickname = env->GetStringUTFChars(nicknameString, &isCopy);
|
||||
const char* message = env->GetStringUTFChars(messageString, &isCopy);
|
||||
const char* macAddress = macAddressString ? env->GetStringUTFChars(macAddressString, &isCopy) : nullptr;
|
||||
|
||||
u8 macAddressArray[6] = { 0 };
|
||||
|
||||
if (macAddress) {
|
||||
bool isBad = false;
|
||||
int sectionCounter = 0;
|
||||
std::size_t start = 0;
|
||||
std::size_t end = 0;
|
||||
|
||||
// Split address string into sections separated by a colon (:)
|
||||
std::string macString = macAddress;
|
||||
while ((end = macString.find(':', start)) != std::string::npos) {
|
||||
if (end != start) {
|
||||
char* endPointer;
|
||||
std::string sectionString = macString.substr(start, end - start);
|
||||
// Each code section must be 2 hex characters
|
||||
if (sectionString.size() != 2) {
|
||||
isBad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned long section = strtoul(sectionString.c_str(), &endPointer, 16);
|
||||
if (*endPointer == 0) {
|
||||
if (sectionCounter >= sizeof(macAddressArray)) {
|
||||
isBad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
macAddressArray[sectionCounter] = (u8) section;
|
||||
sectionCounter++;
|
||||
} else {
|
||||
isBad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
if (!isBad && end != start) {
|
||||
char* endPointer;
|
||||
std::string sectionString = macString.substr(start, end - start);
|
||||
if (sectionString.size() != 8) {
|
||||
isBad = true;
|
||||
} else {
|
||||
unsigned long section = strtoul(sectionString.c_str(), &endPointer, 16);
|
||||
if (*endPointer == 0 && sectionCounter < sizeof(macAddressArray)) {
|
||||
macAddressArray[sectionCounter] = (u32) section;
|
||||
sectionCounter++;
|
||||
} else {
|
||||
isBad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the MAC address is invalid, enable randomization
|
||||
if (isBad) {
|
||||
randomizeMacAddress = true;
|
||||
}
|
||||
}
|
||||
|
||||
MelonDSAndroid::FirmwareConfiguration finalFirmwareConfiguration;
|
||||
strncpy(finalFirmwareConfiguration.username, nickname, sizeof(finalFirmwareConfiguration.username) - 1);
|
||||
strncpy(finalFirmwareConfiguration.message, message, sizeof(finalFirmwareConfiguration.message) - 1);
|
||||
finalFirmwareConfiguration.username[sizeof(finalFirmwareConfiguration.username) - 1] = '\0';
|
||||
finalFirmwareConfiguration.message[sizeof(finalFirmwareConfiguration.message) - 1] = '\0';
|
||||
finalFirmwareConfiguration.language = language;
|
||||
finalFirmwareConfiguration.favouriteColour = colour;
|
||||
finalFirmwareConfiguration.birthdayDay = birthdayDay;
|
||||
finalFirmwareConfiguration.birthdayMonth = birthdayMonth;
|
||||
finalFirmwareConfiguration.randomizeMacAddress = randomizeMacAddress;
|
||||
memcpy(finalFirmwareConfiguration.macAddress, macAddressArray, sizeof(macAddressArray));
|
||||
|
||||
if (isCopy) {
|
||||
env->ReleaseStringUTFChars(nicknameString, nickname);
|
||||
env->ReleaseStringUTFChars(messageString, message);
|
||||
if (macAddress) env->ReleaseStringUTFChars(macAddressString, macAddress);
|
||||
}
|
||||
|
||||
return finalFirmwareConfiguration;
|
||||
}
|
||||
|
||||
GPU::RenderSettings MelonDSAndroidConfiguration::buildRenderSettings(JNIEnv* env, jobject renderSettings) {
|
||||
jclass renderSettingsClass = env->GetObjectClass(renderSettings);
|
||||
jboolean threadedRendering = env->GetBooleanField(renderSettings, env->GetFieldID(renderSettingsClass, "threadedRendering", "Z"));
|
||||
return {
|
||||
threadedRendering == JNI_TRUE,
|
||||
1,
|
||||
false
|
||||
};
|
||||
}
|
12
app/src/main/cpp/MelonDSAndroidConfiguration.h
Normal file
12
app/src/main/cpp/MelonDSAndroidConfiguration.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef MELONDSANDROIDCONFIGURATION_H
|
||||
#define MELONDSANDROIDCONFIGURATION_H
|
||||
|
||||
#include "MelonDS.h"
|
||||
|
||||
namespace MelonDSAndroidConfiguration {
|
||||
MelonDSAndroid::EmulatorConfiguration buildEmulatorConfiguration(JNIEnv* env, jobject emulatorConfiguration);
|
||||
MelonDSAndroid::FirmwareConfiguration buildFirmwareConfiguration(JNIEnv* env, jobject firmwareConfiguration);
|
||||
GPU::RenderSettings buildRenderSettings(JNIEnv* env, jobject renderSettings);
|
||||
}
|
||||
|
||||
#endif //MELONDSANDROIDCONFIGURATION_H
|
33
app/src/main/cpp/MelonDSAndroidInterface.cpp
Normal file
33
app/src/main/cpp/MelonDSAndroidInterface.cpp
Normal file
@ -0,0 +1,33 @@
|
||||
#include "JniEnvHandler.h"
|
||||
#include "UriFileHandler.h"
|
||||
#include "MelonDS.h"
|
||||
|
||||
JavaVM* vm;
|
||||
JniEnvHandler* jniEnvHandler;
|
||||
jobject androidUriFileHandler;
|
||||
UriFileHandler* fileHandler;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
JNIEXPORT void JNICALL
|
||||
Java_me_magnum_melonds_MelonDSAndroidInterface_setup(JNIEnv* env, jobject thiz, jobject uriFileHandler)
|
||||
{
|
||||
env->GetJavaVM(&vm);
|
||||
jniEnvHandler = new JniEnvHandler(vm);
|
||||
androidUriFileHandler = env->NewGlobalRef(uriFileHandler);
|
||||
fileHandler = new UriFileHandler(jniEnvHandler, androidUriFileHandler);
|
||||
|
||||
MelonDSAndroid::fileHandler = fileHandler;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_me_magnum_melonds_MelonDSAndroidInterface_cleanup(JNIEnv* env, jobject thiz)
|
||||
{
|
||||
env->DeleteGlobalRef(androidUriFileHandler);
|
||||
androidUriFileHandler = nullptr;
|
||||
vm = nullptr;
|
||||
|
||||
delete fileHandler;
|
||||
delete jniEnvHandler;
|
||||
}
|
||||
}
|
@ -10,12 +10,10 @@
|
||||
#include <android/asset_manager_jni.h>
|
||||
#include "UriFileHandler.h"
|
||||
#include "JniEnvHandler.h"
|
||||
#include "MelonDSAndroidConfiguration.h"
|
||||
|
||||
#define MAX_CHEAT_SIZE (2*64)
|
||||
|
||||
MelonDSAndroid::EmulatorConfiguration buildEmulatorConfiguration(JNIEnv* env, jobject emulatorConfiguration);
|
||||
MelonDSAndroid::FirmwareConfiguration buildFirmwareConfiguration(JNIEnv* env, jobject firmwareConfiguration);
|
||||
GPU::RenderSettings buildRenderSettings(JNIEnv* env, jobject renderSettings);
|
||||
void* emulate(void*);
|
||||
|
||||
pthread_t emuThread;
|
||||
@ -33,30 +31,22 @@ float fastForwardSpeedMultiplier;
|
||||
bool limitFps = true;
|
||||
bool isFastForwardEnabled = false;
|
||||
jobject globalAssetManager;
|
||||
jobject androidUriFileHandler;
|
||||
UriFileHandler* fileHandler;
|
||||
JniEnvHandler* jniEnvHandler;
|
||||
JavaVM* vm;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
JNIEXPORT void JNICALL
|
||||
Java_me_magnum_melonds_MelonEmulator_setupEmulator(JNIEnv* env, jobject thiz, jobject emulatorConfiguration, jobject javaAssetManager, jobject uriFileHandler, jobject textureBuffer)
|
||||
Java_me_magnum_melonds_MelonEmulator_setupEmulator(JNIEnv* env, jobject thiz, jobject emulatorConfiguration, jobject javaAssetManager, jobject textureBuffer)
|
||||
{
|
||||
env->GetJavaVM(&vm);
|
||||
jniEnvHandler = new JniEnvHandler(vm);
|
||||
MelonDSAndroid::EmulatorConfiguration finalEmulatorConfiguration = buildEmulatorConfiguration(env, emulatorConfiguration);
|
||||
MelonDSAndroid::EmulatorConfiguration finalEmulatorConfiguration = MelonDSAndroidConfiguration::buildEmulatorConfiguration(env, emulatorConfiguration);
|
||||
fastForwardSpeedMultiplier = finalEmulatorConfiguration.fastForwardSpeedMultiplier;
|
||||
|
||||
globalAssetManager = env->NewGlobalRef(javaAssetManager);
|
||||
androidUriFileHandler = env->NewGlobalRef(uriFileHandler);
|
||||
globalAssetManager = env->NewGlobalRef(javaAssetManager);;
|
||||
|
||||
AAssetManager* assetManager = AAssetManager_fromJava(env, globalAssetManager);
|
||||
fileHandler = new UriFileHandler(jniEnvHandler, androidUriFileHandler);
|
||||
|
||||
u32* textureBufferPointer = (u32*) env->GetDirectBufferAddress(textureBuffer);
|
||||
|
||||
MelonDSAndroid::setup(finalEmulatorConfiguration, assetManager, fileHandler, textureBufferPointer);
|
||||
MelonDSAndroid::setup(finalEmulatorConfiguration, assetManager, textureBufferPointer);
|
||||
paused = false;
|
||||
}
|
||||
|
||||
@ -356,10 +346,6 @@ Java_me_magnum_melonds_MelonEmulator_stopEmulation(JNIEnv* env, jobject thiz)
|
||||
|
||||
env->DeleteGlobalRef(globalAssetManager);
|
||||
globalAssetManager = nullptr;
|
||||
env->DeleteGlobalRef(androidUriFileHandler);
|
||||
androidUriFileHandler = nullptr;
|
||||
delete fileHandler;
|
||||
delete jniEnvHandler;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
@ -402,7 +388,7 @@ Java_me_magnum_melonds_MelonEmulator_setFastForwardEnabled(JNIEnv* env, jobject
|
||||
JNIEXPORT void JNICALL
|
||||
Java_me_magnum_melonds_MelonEmulator_updateEmulatorConfiguration(JNIEnv* env, jobject thiz, jobject emulatorConfiguration)
|
||||
{
|
||||
MelonDSAndroid::EmulatorConfiguration newConfiguration = buildEmulatorConfiguration(env, emulatorConfiguration);
|
||||
MelonDSAndroid::EmulatorConfiguration newConfiguration = MelonDSAndroidConfiguration::buildEmulatorConfiguration(env, emulatorConfiguration);
|
||||
MelonDSAndroid::updateEmulatorConfiguration(newConfiguration);
|
||||
fastForwardSpeedMultiplier = newConfiguration.fastForwardSpeedMultiplier;
|
||||
|
||||
@ -413,195 +399,6 @@ Java_me_magnum_melonds_MelonEmulator_updateEmulatorConfiguration(JNIEnv* env, jo
|
||||
}
|
||||
}
|
||||
|
||||
MelonDSAndroid::EmulatorConfiguration buildEmulatorConfiguration(JNIEnv* env, jobject emulatorConfiguration) {
|
||||
jclass emulatorConfigurationClass = env->GetObjectClass(emulatorConfiguration);
|
||||
jclass uriClass = env->FindClass("android/net/Uri");
|
||||
jclass consoleTypeEnumClass = env->FindClass("me/magnum/melonds/domain/model/ConsoleType");
|
||||
jclass audioBitrateEnumClass = env->FindClass("me/magnum/melonds/domain/model/AudioBitrate");
|
||||
jclass audioInterpolationEnumClass = env->FindClass("me/magnum/melonds/domain/model/AudioInterpolation");
|
||||
jclass audioLatencyEnumClass = env->FindClass("me/magnum/melonds/domain/model/AudioLatency");
|
||||
jclass micSourceEnumClass = env->FindClass("me/magnum/melonds/domain/model/MicSource");
|
||||
|
||||
jmethodID uriToStringMethod = env->GetMethodID(uriClass, "toString", "()Ljava/lang/String;");
|
||||
|
||||
jboolean useCustomBios = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "useCustomBios", "Z"));
|
||||
jobject dsBios7Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsBios7Uri", "Landroid/net/Uri;"));
|
||||
jobject dsBios9Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsBios9Uri", "Landroid/net/Uri;"));
|
||||
jobject dsFirmwareUri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsFirmwareUri", "Landroid/net/Uri;"));
|
||||
jobject dsiBios7Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiBios7Uri", "Landroid/net/Uri;"));
|
||||
jobject dsiBios9Uri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiBios9Uri", "Landroid/net/Uri;"));
|
||||
jobject dsiFirmwareUri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiFirmwareUri", "Landroid/net/Uri;"));
|
||||
jobject dsiNandUri = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiNandUri", "Landroid/net/Uri;"));
|
||||
jstring internalFilesDir = (jstring) env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "internalDirectory", "Ljava/lang/String;"));
|
||||
jfloat fastForwardMaxSpeed = env->GetFloatField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "fastForwardSpeedMultiplier", "F"));
|
||||
jboolean enableRewind = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rewindEnabled", "Z"));
|
||||
jint rewindPeriodSeconds = env->GetIntField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rewindPeriodSeconds", "I"));
|
||||
jint rewindWindowSeconds = env->GetIntField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rewindWindowSeconds", "I"));
|
||||
jboolean useJit = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "useJit", "Z"));
|
||||
jobject consoleTypeEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "consoleType", "Lme/magnum/melonds/domain/model/ConsoleType;"));
|
||||
jint consoleType = env->GetIntField(consoleTypeEnum, env->GetFieldID(consoleTypeEnumClass, "consoleType", "I"));
|
||||
jboolean soundEnabled = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "soundEnabled", "Z"));
|
||||
jint volume = env->GetIntField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "volume", "I"));
|
||||
jobject audioInterpolationEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "audioInterpolation", "Lme/magnum/melonds/domain/model/AudioInterpolation;"));
|
||||
jint audioInterpolation = env->GetIntField(audioInterpolationEnum, env->GetFieldID(audioInterpolationEnumClass, "interpolationValue", "I"));
|
||||
jobject audioBitrateEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "audioBitrate", "Lme/magnum/melonds/domain/model/AudioBitrate;"));
|
||||
jint audioBitrate = env->GetIntField(audioBitrateEnum, env->GetFieldID(audioBitrateEnumClass, "bitrateValue", "I"));
|
||||
jobject audioLatencyEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "audioLatency", "Lme/magnum/melonds/domain/model/AudioLatency;"));
|
||||
jint audioLatency = env->GetIntField(audioLatencyEnum, env->GetFieldID(audioLatencyEnumClass, "latencyValue", "I"));
|
||||
jobject micSourceEnum = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "micSource", "Lme/magnum/melonds/domain/model/MicSource;"));
|
||||
jint micSource = env->GetIntField(micSourceEnum, env->GetFieldID(micSourceEnumClass, "sourceValue", "I"));
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
jstring dsBios7String = dsBios7Uri ? (jstring) env->CallObjectMethod(dsBios7Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsBios9String = dsBios9Uri ? (jstring) env->CallObjectMethod(dsBios9Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsFirmwareString = dsFirmwareUri ? (jstring) env->CallObjectMethod(dsFirmwareUri, uriToStringMethod) : nullptr;
|
||||
jstring dsiBios7String = dsiBios7Uri ? (jstring) env->CallObjectMethod(dsiBios7Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsiBios9String = dsiBios9Uri ? (jstring) env->CallObjectMethod(dsiBios9Uri, uriToStringMethod) : nullptr;
|
||||
jstring dsiFirmwareString = dsiFirmwareUri ? (jstring) env->CallObjectMethod(dsiFirmwareUri, uriToStringMethod) : nullptr;
|
||||
jstring dsiNandString = dsiNandUri ? (jstring) env->CallObjectMethod(dsiNandUri, uriToStringMethod) : nullptr;
|
||||
const char* dsBios7Path = dsBios7Uri ? env->GetStringUTFChars(dsBios7String, &isCopy) : nullptr;
|
||||
const char* dsBios9Path = dsBios9Uri ? env->GetStringUTFChars(dsBios9String, &isCopy) : nullptr;
|
||||
const char* dsFirmwarePath = dsFirmwareUri ? env->GetStringUTFChars(dsFirmwareString, &isCopy) : nullptr;
|
||||
const char* dsiBios7Path = dsiBios7Uri ? env->GetStringUTFChars(dsiBios7String, &isCopy) : nullptr;
|
||||
const char* dsiBios9Path = dsiBios9Uri ? env->GetStringUTFChars(dsiBios9String, &isCopy) : nullptr;
|
||||
const char* dsiFirmwarePath = dsiFirmwareUri ? env->GetStringUTFChars(dsiFirmwareString, &isCopy) : nullptr;
|
||||
const char* dsiNandPath = dsiNandUri ? env->GetStringUTFChars(dsiNandString, &isCopy) : nullptr;
|
||||
const char* internalDir = env->GetStringUTFChars(internalFilesDir, JNI_FALSE);
|
||||
jobject firmwareConfigurationObject = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "firmwareConfiguration", "Lme/magnum/melonds/domain/model/FirmwareConfiguration;"));
|
||||
jobject rendererConfigurationObject = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rendererConfiguration", "Lme/magnum/melonds/domain/model/RendererConfiguration;"));
|
||||
|
||||
MelonDSAndroid::EmulatorConfiguration finalEmulatorConfiguration;
|
||||
finalEmulatorConfiguration.userInternalFirmwareAndBios = !useCustomBios;
|
||||
finalEmulatorConfiguration.dsBios7Path = const_cast<char*>(dsBios7Path);
|
||||
finalEmulatorConfiguration.dsBios9Path = const_cast<char*>(dsBios9Path);
|
||||
finalEmulatorConfiguration.dsFirmwarePath = const_cast<char*>(dsFirmwarePath);
|
||||
finalEmulatorConfiguration.dsiBios7Path = const_cast<char*>(dsiBios7Path);
|
||||
finalEmulatorConfiguration.dsiBios9Path = const_cast<char*>(dsiBios9Path);
|
||||
finalEmulatorConfiguration.dsiFirmwarePath = const_cast<char*>(dsiFirmwarePath);
|
||||
finalEmulatorConfiguration.dsiNandPath = const_cast<char*>(dsiNandPath);
|
||||
finalEmulatorConfiguration.internalFilesDir = const_cast<char*>(internalDir);
|
||||
finalEmulatorConfiguration.fastForwardSpeedMultiplier = fastForwardMaxSpeed;
|
||||
finalEmulatorConfiguration.useJit = useJit;
|
||||
finalEmulatorConfiguration.consoleType = consoleType;
|
||||
finalEmulatorConfiguration.soundEnabled = soundEnabled;
|
||||
finalEmulatorConfiguration.volume = volume;
|
||||
finalEmulatorConfiguration.audioInterpolation = audioInterpolation;
|
||||
finalEmulatorConfiguration.audioBitrate = audioBitrate;
|
||||
finalEmulatorConfiguration.audioLatency = audioLatency;
|
||||
finalEmulatorConfiguration.micSource = micSource;
|
||||
finalEmulatorConfiguration.firmwareConfiguration = buildFirmwareConfiguration(env, firmwareConfigurationObject);
|
||||
finalEmulatorConfiguration.renderSettings = buildRenderSettings(env, rendererConfigurationObject);
|
||||
finalEmulatorConfiguration.rewindEnabled = enableRewind ? 1 : 0;
|
||||
finalEmulatorConfiguration.rewindCaptureSpacingSeconds = rewindPeriodSeconds;
|
||||
finalEmulatorConfiguration.rewindLengthSeconds = rewindWindowSeconds;
|
||||
return finalEmulatorConfiguration;
|
||||
}
|
||||
|
||||
MelonDSAndroid::FirmwareConfiguration buildFirmwareConfiguration(JNIEnv* env, jobject firmwareConfiguration) {
|
||||
jclass firmwareConfigurationClass = env->GetObjectClass(firmwareConfiguration);
|
||||
jstring nicknameString = (jstring) env->GetObjectField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "nickname", "Ljava/lang/String;"));
|
||||
jstring messageString = (jstring) env->GetObjectField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "message", "Ljava/lang/String;"));
|
||||
int language = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "language", "I"));
|
||||
int colour = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "favouriteColour", "I"));
|
||||
int birthdayDay = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "birthdayDay", "I"));
|
||||
int birthdayMonth = env->GetIntField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "birthdayMonth", "I"));
|
||||
bool randomizeMacAddress = env->GetBooleanField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "randomizeMacAddress", "Z"));
|
||||
jstring macAddressString = (jstring) env->GetObjectField(firmwareConfiguration, env->GetFieldID(firmwareConfigurationClass, "internalMacAddress", "Ljava/lang/String;"));
|
||||
|
||||
jboolean isCopy = JNI_FALSE;
|
||||
const char* nickname = env->GetStringUTFChars(nicknameString, &isCopy);
|
||||
const char* message = env->GetStringUTFChars(messageString, &isCopy);
|
||||
const char* macAddress = macAddressString ? env->GetStringUTFChars(macAddressString, &isCopy) : nullptr;
|
||||
|
||||
u8 macAddressArray[6] = { 0 };
|
||||
|
||||
if (macAddress) {
|
||||
bool isBad = false;
|
||||
int sectionCounter = 0;
|
||||
std::size_t start = 0;
|
||||
std::size_t end = 0;
|
||||
|
||||
// Split address string into sections separated by a colon (:)
|
||||
std::string macString = macAddress;
|
||||
while ((end = macString.find(':', start)) != std::string::npos) {
|
||||
if (end != start) {
|
||||
char* endPointer;
|
||||
std::string sectionString = macString.substr(start, end - start);
|
||||
// Each code section must be 2 hex characters
|
||||
if (sectionString.size() != 2) {
|
||||
isBad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
unsigned long section = strtoul(sectionString.c_str(), &endPointer, 16);
|
||||
if (*endPointer == 0) {
|
||||
if (sectionCounter >= sizeof(macAddressArray)) {
|
||||
isBad = true;
|
||||
break;
|
||||
}
|
||||
|
||||
macAddressArray[sectionCounter] = (u8) section;
|
||||
sectionCounter++;
|
||||
} else {
|
||||
isBad = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
if (!isBad && end != start) {
|
||||
char* endPointer;
|
||||
std::string sectionString = macString.substr(start, end - start);
|
||||
if (sectionString.size() != 8) {
|
||||
isBad = true;
|
||||
} else {
|
||||
unsigned long section = strtoul(sectionString.c_str(), &endPointer, 16);
|
||||
if (*endPointer == 0 && sectionCounter < sizeof(macAddressArray)) {
|
||||
macAddressArray[sectionCounter] = (u32) section;
|
||||
sectionCounter++;
|
||||
} else {
|
||||
isBad = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the MAC address is invalid, enable randomization
|
||||
if (isBad) {
|
||||
randomizeMacAddress = true;
|
||||
}
|
||||
}
|
||||
|
||||
MelonDSAndroid::FirmwareConfiguration finalFirmwareConfiguration;
|
||||
strncpy(finalFirmwareConfiguration.username, nickname, sizeof(finalFirmwareConfiguration.username) - 1);
|
||||
strncpy(finalFirmwareConfiguration.message, message, sizeof(finalFirmwareConfiguration.message) - 1);
|
||||
finalFirmwareConfiguration.username[sizeof(finalFirmwareConfiguration.username) - 1] = '\0';
|
||||
finalFirmwareConfiguration.message[sizeof(finalFirmwareConfiguration.message) - 1] = '\0';
|
||||
finalFirmwareConfiguration.language = language;
|
||||
finalFirmwareConfiguration.favouriteColour = colour;
|
||||
finalFirmwareConfiguration.birthdayDay = birthdayDay;
|
||||
finalFirmwareConfiguration.birthdayMonth = birthdayMonth;
|
||||
finalFirmwareConfiguration.randomizeMacAddress = randomizeMacAddress;
|
||||
memcpy(finalFirmwareConfiguration.macAddress, macAddressArray, sizeof(macAddressArray));
|
||||
|
||||
if (isCopy) {
|
||||
env->ReleaseStringUTFChars(nicknameString, nickname);
|
||||
env->ReleaseStringUTFChars(messageString, message);
|
||||
if (macAddress) env->ReleaseStringUTFChars(macAddressString, macAddress);
|
||||
}
|
||||
|
||||
return finalFirmwareConfiguration;
|
||||
}
|
||||
|
||||
GPU::RenderSettings buildRenderSettings(JNIEnv* env, jobject renderSettings) {
|
||||
jclass renderSettingsClass = env->GetObjectClass(renderSettings);
|
||||
jboolean threadedRendering = env->GetBooleanField(renderSettings, env->GetFieldID(renderSettingsClass, "threadedRendering", "Z"));
|
||||
return {
|
||||
threadedRendering == JNI_TRUE,
|
||||
1,
|
||||
false
|
||||
};
|
||||
}
|
||||
|
||||
double getCurrentMillis() {
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_REALTIME, &now);
|
||||
|
@ -0,0 +1,8 @@
|
||||
package me.magnum.melonds
|
||||
|
||||
import me.magnum.melonds.common.UriFileHandler
|
||||
|
||||
object MelonDSAndroidInterface {
|
||||
external fun setup(uriFileHandler: UriFileHandler)
|
||||
external fun cleanup()
|
||||
}
|
@ -8,6 +8,8 @@ import androidx.hilt.work.HiltWorkerFactory
|
||||
import androidx.work.Configuration
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
import io.reactivex.disposables.Disposable
|
||||
import me.magnum.melonds.common.UriFileHandler
|
||||
import me.magnum.melonds.common.uridelegates.UriHandler
|
||||
import me.magnum.melonds.domain.repositories.SettingsRepository
|
||||
import me.magnum.melonds.migrations.Migrator
|
||||
import javax.inject.Inject
|
||||
@ -16,11 +18,16 @@ import javax.inject.Inject
|
||||
class MelonDSApplication : Application(), Configuration.Provider {
|
||||
companion object {
|
||||
const val NOTIFICATION_CHANNEL_ID_BACKGROUND_TASKS = "channel_cheat_importing"
|
||||
|
||||
init {
|
||||
System.loadLibrary("melonDS-android-frontend")
|
||||
}
|
||||
}
|
||||
|
||||
@Inject lateinit var workerFactory: HiltWorkerFactory
|
||||
@Inject lateinit var settingsRepository: SettingsRepository
|
||||
@Inject lateinit var migrator: Migrator
|
||||
@Inject lateinit var uriHandler: UriHandler
|
||||
|
||||
private var themeObserverDisposable: Disposable? = null
|
||||
|
||||
@ -29,6 +36,7 @@ class MelonDSApplication : Application(), Configuration.Provider {
|
||||
createNotificationChannels()
|
||||
applyTheme()
|
||||
performMigrations()
|
||||
MelonDSAndroidInterface.setup(UriFileHandler(this, uriHandler))
|
||||
}
|
||||
|
||||
private fun createNotificationChannels() {
|
||||
@ -60,5 +68,6 @@ class MelonDSApplication : Application(), Configuration.Provider {
|
||||
override fun onTerminate() {
|
||||
super.onTerminate()
|
||||
themeObserverDisposable?.dispose()
|
||||
MelonDSAndroidInterface.cleanup()
|
||||
}
|
||||
}
|
@ -35,7 +35,7 @@ object MelonEmulator {
|
||||
DSI_NAND_BAD
|
||||
}
|
||||
|
||||
external fun setupEmulator(emulatorConfiguration: EmulatorConfiguration, assetManager: AssetManager?, uriFileHandler: UriFileHandler, textureBuffer: ByteBuffer)
|
||||
external fun setupEmulator(emulatorConfiguration: EmulatorConfiguration, assetManager: AssetManager?, textureBuffer: ByteBuffer)
|
||||
|
||||
external fun setupCheats(cheats: Array<Cheat>)
|
||||
|
||||
|
@ -30,7 +30,6 @@ import io.reactivex.subjects.PublishSubject
|
||||
import me.magnum.melonds.MelonEmulator
|
||||
import me.magnum.melonds.R
|
||||
import me.magnum.melonds.common.Schedulers
|
||||
import me.magnum.melonds.common.UriFileHandler
|
||||
import me.magnum.melonds.common.uridelegates.UriHandler
|
||||
import me.magnum.melonds.common.vibration.TouchVibrator
|
||||
import me.magnum.melonds.databinding.ActivityEmulatorBinding
|
||||
@ -46,8 +45,8 @@ import me.magnum.melonds.ui.emulator.DSRenderer.RendererListener
|
||||
import me.magnum.melonds.ui.emulator.firmware.FirmwareEmulatorDelegate
|
||||
import me.magnum.melonds.ui.emulator.input.*
|
||||
import me.magnum.melonds.ui.emulator.rewind.EdgeSpacingDecorator
|
||||
import me.magnum.melonds.ui.emulator.rewind.model.RewindSaveState
|
||||
import me.magnum.melonds.ui.emulator.rewind.RewindSaveStateAdapter
|
||||
import me.magnum.melonds.ui.emulator.rewind.model.RewindSaveState
|
||||
import me.magnum.melonds.ui.emulator.rom.RomEmulatorDelegate
|
||||
import me.magnum.melonds.ui.settings.SettingsActivity
|
||||
import me.magnum.melonds.utils.PackageManagerCompat
|
||||
@ -64,10 +63,6 @@ class EmulatorActivity : AppCompatActivity(), RendererListener {
|
||||
const val KEY_BOOT_FIRMWARE_CONSOLE = "boot_firmware_console"
|
||||
private const val KEY_BOOT_FIRMWARE_ONLY = "boot_firmware_only"
|
||||
|
||||
init {
|
||||
System.loadLibrary("melonDS-android-frontend")
|
||||
}
|
||||
|
||||
fun getRomEmulatorActivityIntent(context: Context, rom: Rom): Intent {
|
||||
return Intent(context, EmulatorActivity::class.java).apply {
|
||||
putExtra(KEY_ROM, RomParcelable(rom))
|
||||
@ -520,10 +515,6 @@ class EmulatorActivity : AppCompatActivity(), RendererListener {
|
||||
}
|
||||
}
|
||||
|
||||
fun buildUriFileHandler(): UriFileHandler {
|
||||
return UriFileHandler(this, uriHandler)
|
||||
}
|
||||
|
||||
fun getRendererTextureBuffer(): ByteBuffer {
|
||||
return dsRenderer.textureBuffer
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ class FirmwareEmulatorDelegate(activity: EmulatorActivity) : EmulatorDelegate(ac
|
||||
return getEmulatorLaunchConfiguration(firmwareConsoleType).flatMapCompletable { emulatorConfiguration ->
|
||||
Completable.create {
|
||||
activity.viewModel.loadLayoutForFirmware()
|
||||
MelonEmulator.setupEmulator(emulatorConfiguration, activity.assets, activity.buildUriFileHandler(), activity.getRendererTextureBuffer())
|
||||
MelonEmulator.setupEmulator(emulatorConfiguration, activity.assets, activity.getRendererTextureBuffer())
|
||||
|
||||
val loadResult = MelonEmulator.bootFirmware()
|
||||
if (loadResult != MelonEmulator.FirmwareLoadResult.SUCCESS) {
|
||||
|
@ -63,7 +63,7 @@ class RomEmulatorDelegate(activity: EmulatorActivity, private val picasso: Picas
|
||||
Pair(cheats, emulatorConfiguration)
|
||||
}.flatMap { (cheats, emulatorConfiguration) ->
|
||||
Single.create<MelonEmulator.LoadResult> { emitter ->
|
||||
MelonEmulator.setupEmulator(emulatorConfiguration, activity.assets, activity.buildUriFileHandler(), activity.getRendererTextureBuffer())
|
||||
MelonEmulator.setupEmulator(emulatorConfiguration, activity.assets, activity.getRendererTextureBuffer())
|
||||
|
||||
val rom = romPair.first
|
||||
val romPath = romPair.second
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 159c113545484fc38c0d74c7f8d066a626093911
|
||||
Subproject commit 69de234b13b7064499b8e06d2ff46b96b152541f
|
Loading…
Reference in New Issue
Block a user