mirror of
https://github.com/rafaelvcaetano/melonDS-android.git
synced 2025-03-01 02:06:22 +00:00
Add DSi support
This commit is contained in:
parent
9375033c0d
commit
9d913e56e9
3
app/proguard-rules.pro
vendored
3
app/proguard-rules.pro
vendored
@ -23,4 +23,5 @@
|
||||
-keepclassmembers enum * { *; }
|
||||
|
||||
-keep class me.magnum.melonds.domain.model.RendererConfiguration { *; }
|
||||
-keep class me.magnum.melonds.domain.model.EmulatorConfiguration { *; }
|
||||
-keep class me.magnum.melonds.domain.model.EmulatorConfiguration { *; }
|
||||
-keep class me.magnum.melonds.domain.model.ConsoleType { *; }
|
@ -25,17 +25,24 @@ JNIEXPORT void JNICALL
|
||||
Java_me_magnum_melonds_MelonEmulator_setupEmulator(JNIEnv* env, jclass type, jobject emulatorConfiguration, jobject javaAssetManager)
|
||||
{
|
||||
jclass emulatorConfigurationClass = env->GetObjectClass(emulatorConfiguration);
|
||||
jstring configDir = (jstring) env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "configDirectory", "Ljava/lang/String;"));
|
||||
jclass consoleTypeEnumClass = env->FindClass("me/magnum/melonds/domain/model/ConsoleType");
|
||||
jstring dsConfigDir = (jstring) env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsConfigDirectory", "Ljava/lang/String;"));
|
||||
jstring dsiConfigDir = (jstring) env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "dsiConfigDirectory", "Ljava/lang/String;"));
|
||||
jboolean useJit = env->GetBooleanField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "useJit", "Z"));
|
||||
const char* dir = env->GetStringUTFChars(configDir, JNI_FALSE);
|
||||
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"));
|
||||
const char* dsDir = env->GetStringUTFChars(dsConfigDir, JNI_FALSE);
|
||||
const char* dsiDir = env->GetStringUTFChars(dsiConfigDir, JNI_FALSE);
|
||||
jobject rendererConfigurationObject = env->GetObjectField(emulatorConfiguration, env->GetFieldID(emulatorConfigurationClass, "rendererConfiguration", "Lme/magnum/melonds/domain/model/RendererConfiguration;"));
|
||||
|
||||
jobject globalAssetManager = env->NewGlobalRef(javaAssetManager);
|
||||
AAssetManager* assetManager = AAssetManager_fromJava(env, globalAssetManager);
|
||||
|
||||
MelonDSAndroid::EmulatorConfiguration finalEmulatorConfiguration;
|
||||
finalEmulatorConfiguration.configDir = const_cast<char*>(dir);
|
||||
finalEmulatorConfiguration.dsConfigDir = const_cast<char*>(dsDir);
|
||||
finalEmulatorConfiguration.dsiConfigDir = const_cast<char*>(dsiDir);
|
||||
finalEmulatorConfiguration.useJit = useJit;
|
||||
finalEmulatorConfiguration.consoleType = consoleType;
|
||||
finalEmulatorConfiguration.renderSettings = buildRenderSettings(env, rendererConfigurationObject);
|
||||
MelonDSAndroid::setup(finalEmulatorConfiguration, assetManager);
|
||||
}
|
||||
@ -218,7 +225,7 @@ void* emulate(void*)
|
||||
if (frameLimitError < -frameRate)
|
||||
frameLimitError = -frameRate;
|
||||
if (frameLimitError > frameRate)
|
||||
frameLimitError =frameRate;
|
||||
frameLimitError = frameRate;
|
||||
|
||||
if (round(frameLimitError) > 0.0)
|
||||
{
|
||||
|
@ -2,13 +2,16 @@ package me.magnum.melonds.di
|
||||
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.net.Uri
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.GsonBuilder
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.components.ApplicationComponent
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import me.magnum.melonds.utils.UriTypeHierarchyAdapter
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@ -25,6 +28,8 @@ object AppModule {
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideGson(): Gson {
|
||||
return Gson()
|
||||
return GsonBuilder()
|
||||
.registerTypeHierarchyAdapter(Uri::class.java, UriTypeHierarchyAdapter())
|
||||
.create()
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package me.magnum.melonds.domain.model
|
||||
|
||||
enum class ConsoleType(val consoleType: Int) {
|
||||
DS(0),
|
||||
DSi(1);
|
||||
|
||||
companion object {
|
||||
fun valueOfIgnoreCase(value: String): ConsoleType {
|
||||
values().forEach {
|
||||
if (it.name.equals(value, true))
|
||||
return it
|
||||
}
|
||||
throw IllegalArgumentException("Value $value does not represent an enum entry")
|
||||
}
|
||||
}
|
||||
}
|
@ -1,3 +1,9 @@
|
||||
package me.magnum.melonds.domain.model
|
||||
|
||||
data class EmulatorConfiguration(val configDirectory: String, val useJit: Boolean, val rendererConfiguration: RendererConfiguration)
|
||||
data class EmulatorConfiguration(
|
||||
val dsConfigDirectory: String,
|
||||
val dsiConfigDirectory: String,
|
||||
val useJit: Boolean,
|
||||
val consoleType: ConsoleType,
|
||||
val rendererConfiguration: RendererConfiguration
|
||||
)
|
@ -2,7 +2,7 @@ package me.magnum.melonds.domain.model
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
data class RomConfig(private var loadGbaCart: Boolean = false, var gbaCartPath: Uri? = null, var gbaSavePath: Uri? = null) {
|
||||
data class RomConfig(var runtimeConsoleType: RuntimeConsoleType = RuntimeConsoleType.DEFAULT, private var loadGbaCart: Boolean = false, var gbaCartPath: Uri? = null, var gbaSavePath: Uri? = null) {
|
||||
fun loadGbaCart(): Boolean {
|
||||
return loadGbaCart
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package me.magnum.melonds.domain.model
|
||||
|
||||
enum class RuntimeConsoleType(val targetConsoleType: ConsoleType?) {
|
||||
DEFAULT(null),
|
||||
DS(ConsoleType.DS),
|
||||
DSi(ConsoleType.DSi)
|
||||
}
|
@ -12,7 +12,9 @@ interface SettingsRepository {
|
||||
|
||||
fun getRomSearchDirectories(): Array<Uri>
|
||||
|
||||
fun getBiosDirectory(): Uri?
|
||||
fun getDefaultConsoleType(): ConsoleType
|
||||
fun getDsBiosDirectory(): Uri?
|
||||
fun getDsiBiosDirectory(): Uri?
|
||||
fun showBootScreen(): Boolean
|
||||
fun isJitEnabled(): Boolean
|
||||
|
||||
@ -32,7 +34,8 @@ interface SettingsRepository {
|
||||
fun observeTheme(): Observable<Theme>
|
||||
fun observeRomSearchDirectories(): Observable<Array<Uri>>
|
||||
|
||||
fun setBiosDirectory(directoryUri: Uri)
|
||||
fun setDsBiosDirectory(directoryUri: Uri)
|
||||
fun setDsiBiosDirectory(directoryUri: Uri)
|
||||
fun addRomSearchDirectory(directoryUri: Uri)
|
||||
fun setControllerConfiguration(controllerConfiguration: ControllerConfiguration)
|
||||
fun setRomSortingMode(sortingMode: SortingMode)
|
||||
|
@ -41,14 +41,24 @@ class SharedPreferencesSettingsRepository(private val context: Context, private
|
||||
}
|
||||
|
||||
override fun getEmulatorConfiguration(): EmulatorConfiguration {
|
||||
val biosDirUri = getBiosDirectory() ?: throw IllegalStateException("BIOS directory not set")
|
||||
val biosDirPath = FileUtils.getAbsolutePathFromSAFUri(context, biosDirUri)
|
||||
val consoleType = getDefaultConsoleType()
|
||||
val dsBiosDirUri = getDsBiosDirectory()
|
||||
val dsiBiosDirUri = getDsiBiosDirectory()
|
||||
|
||||
val configDirectoryPath = "$biosDirPath/"
|
||||
// Ensure all BIOS dirs are set. DSi requires both dirs to be set
|
||||
if (dsBiosDirUri == null || (consoleType == ConsoleType.DSi && dsiBiosDirUri == null))
|
||||
throw IllegalStateException("BIOS directory not set")
|
||||
|
||||
val dsBiosDirPath = FileUtils.getAbsolutePathFromSAFUri(context, dsBiosDirUri)
|
||||
val dsiBiosDirPath = FileUtils.getAbsolutePathFromSAFUri(context, dsiBiosDirUri)
|
||||
val dsConfigDirectoryPath = "$dsBiosDirPath/"
|
||||
val dsiConfigDirectoryPath = "$dsiBiosDirPath/"
|
||||
|
||||
return EmulatorConfiguration(
|
||||
configDirectoryPath,
|
||||
dsConfigDirectoryPath,
|
||||
dsiConfigDirectoryPath,
|
||||
isJitEnabled(),
|
||||
consoleType,
|
||||
RendererConfiguration(
|
||||
getVideoFiltering(),
|
||||
isThreadedRenderingEnabled()
|
||||
@ -66,11 +76,21 @@ class SharedPreferencesSettingsRepository(private val context: Context, private
|
||||
return dirPreference?.map { Uri.parse(it) }?.toTypedArray() ?: emptyArray()
|
||||
}
|
||||
|
||||
override fun getBiosDirectory(): Uri? {
|
||||
override fun getDefaultConsoleType(): ConsoleType {
|
||||
val consoleTypePreference = preferences.getString("console_type", "ds")!!
|
||||
return ConsoleType.valueOfIgnoreCase(consoleTypePreference)
|
||||
}
|
||||
|
||||
override fun getDsBiosDirectory(): Uri? {
|
||||
val dirPreference = preferences.getStringSet("bios_dir", null)?.firstOrNull()
|
||||
return dirPreference?.let { Uri.parse(it) }
|
||||
}
|
||||
|
||||
override fun getDsiBiosDirectory(): Uri? {
|
||||
val dirPreference = preferences.getStringSet("dsi_bios_dir", null)?.firstOrNull()
|
||||
return dirPreference?.let { Uri.parse(it) }
|
||||
}
|
||||
|
||||
override fun showBootScreen(): Boolean {
|
||||
return preferences.getBoolean("show_bios", false)
|
||||
}
|
||||
@ -169,12 +189,18 @@ class SharedPreferencesSettingsRepository(private val context: Context, private
|
||||
}
|
||||
}
|
||||
|
||||
override fun setBiosDirectory(directoryUri: Uri) {
|
||||
override fun setDsBiosDirectory(directoryUri: Uri) {
|
||||
preferences.edit {
|
||||
putStringSet("bios_dir", setOf(directoryUri.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun setDsiBiosDirectory(directoryUri: Uri) {
|
||||
preferences.edit {
|
||||
putStringSet("dsi_bios_dir", setOf(directoryUri.toString()))
|
||||
}
|
||||
}
|
||||
|
||||
override fun addRomSearchDirectory(directoryUri: Uri) {
|
||||
preferences.edit {
|
||||
putStringSet("rom_search_dirs", setOf(directoryUri.toString()))
|
||||
|
@ -5,10 +5,7 @@ import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.hilt.lifecycle.ViewModelInject
|
||||
import androidx.lifecycle.ViewModel
|
||||
import io.reactivex.Single
|
||||
import me.magnum.melonds.domain.model.EmulatorConfiguration
|
||||
import me.magnum.melonds.domain.model.Rom
|
||||
import me.magnum.melonds.domain.model.RomConfig
|
||||
import me.magnum.melonds.domain.model.SaveStateSlot
|
||||
import me.magnum.melonds.domain.model.*
|
||||
import me.magnum.melonds.domain.repositories.RomsRepository
|
||||
import me.magnum.melonds.domain.repositories.SettingsRepository
|
||||
import me.magnum.melonds.utils.FileUtils
|
||||
|
@ -4,7 +4,6 @@ import android.Manifest
|
||||
import android.app.SearchManager
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
@ -18,15 +17,14 @@ import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.Observer
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import me.magnum.melonds.R
|
||||
import me.magnum.melonds.domain.model.ConsoleType
|
||||
import me.magnum.melonds.domain.model.Rom
|
||||
import me.magnum.melonds.domain.model.SortingMode
|
||||
import me.magnum.melonds.domain.repositories.SettingsRepository
|
||||
import me.magnum.melonds.parcelables.RomParcelable
|
||||
import me.magnum.melonds.ui.settings.SettingsActivity
|
||||
import me.magnum.melonds.ui.emulator.EmulatorActivity
|
||||
import me.magnum.melonds.ui.settings.SettingsActivity
|
||||
import me.magnum.melonds.utils.ConfigurationUtils
|
||||
import me.magnum.melonds.utils.DirectoryPickerContract
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class RomListActivity : AppCompatActivity() {
|
||||
@ -38,11 +36,21 @@ class RomListActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private val viewModel: RomListViewModel by viewModels()
|
||||
@Inject lateinit var settingsRepository: SettingsRepository
|
||||
|
||||
private val biosPickerLauncher by lazy { registerForActivityResult(DirectoryPickerContract()) {
|
||||
if (checkConfigDirectorySetup(it)) {
|
||||
settingsRepository.setBiosDirectory(it!!)
|
||||
private val dsBiosPickerLauncher by lazy { registerForActivityResult(DirectoryPickerContract()) { uri ->
|
||||
if (uri != null) {
|
||||
viewModel.setDsBiosDirectory(uri)
|
||||
val currentRom = selectedRom
|
||||
if (currentRom != null)
|
||||
loadRom(currentRom)
|
||||
else
|
||||
checkConfigDirectorySetup()
|
||||
}
|
||||
} }
|
||||
private val dsiBiosPickerLauncher by lazy { registerForActivityResult(DirectoryPickerContract()) { uri ->
|
||||
if (uri != null) {
|
||||
viewModel.setDsiBiosDirectory(uri)
|
||||
selectedRom?.let { loadRom(it) }
|
||||
}
|
||||
} }
|
||||
|
||||
@ -141,20 +149,19 @@ class RomListActivity : AppCompatActivity() {
|
||||
Toast.makeText(this, getString(R.string.info_no_storage_permission), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
|
||||
private fun checkConfigDirectorySetup(checkDirectory: Uri? = null): Boolean {
|
||||
val configDir = checkDirectory ?: settingsRepository.getBiosDirectory()
|
||||
when (ConfigurationUtils.checkConfigurationDirectory(this, configDir)) {
|
||||
private fun checkConfigDirectorySetup(): Boolean {
|
||||
when (viewModel.getDsConfigurationDirStatus()) {
|
||||
ConfigurationUtils.ConfigurationDirStatus.VALID -> return true
|
||||
ConfigurationUtils.ConfigurationDirStatus.UNSET -> AlertDialog.Builder(this)
|
||||
.setTitle(R.string.bios_dir_not_set)
|
||||
.setMessage(R.string.bios_dir_not_set_info)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> biosPickerLauncher.launch(null) }
|
||||
.setTitle(R.string.ds_bios_dir_not_set)
|
||||
.setMessage(R.string.ds_bios_dir_not_set_info)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> dsBiosPickerLauncher.launch(null) }
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
ConfigurationUtils.ConfigurationDirStatus.INVALID -> AlertDialog.Builder(this)
|
||||
.setTitle(R.string.incorrect_bios_dir)
|
||||
.setMessage(R.string.incorrect_bios_dir_info)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> biosPickerLauncher.launch(null) }
|
||||
.setMessage(R.string.ds_incorrect_bios_dir_info)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> dsBiosPickerLauncher.launch(null) }
|
||||
.setCancelable(false)
|
||||
.show()
|
||||
}
|
||||
@ -202,13 +209,58 @@ class RomListActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun loadRom(rom: Rom) {
|
||||
if (isStoragePermissionGranted()) {
|
||||
val intent = Intent(this, EmulatorActivity::class.java)
|
||||
intent.putExtra(EmulatorActivity.KEY_ROM, RomParcelable(rom))
|
||||
startActivity(intent)
|
||||
} else {
|
||||
if (!isStoragePermissionGranted()) {
|
||||
selectedRom = rom
|
||||
requestStoragePermission(false)
|
||||
} else {
|
||||
val configurationDirStatus = viewModel.getRomConfigurationDirStatus(rom)
|
||||
if (configurationDirStatus == ConfigurationUtils.ConfigurationDirStatus.VALID) {
|
||||
val intent = Intent(this, EmulatorActivity::class.java)
|
||||
intent.putExtra(EmulatorActivity.KEY_ROM, RomParcelable(rom))
|
||||
startActivity(intent)
|
||||
} else {
|
||||
selectedRom = rom
|
||||
when (viewModel.getRomTargetConsoleType(rom)) {
|
||||
ConsoleType.DS -> {
|
||||
val titleRes: Int
|
||||
val messageRes: Int
|
||||
if (configurationDirStatus == ConfigurationUtils.ConfigurationDirStatus.UNSET) {
|
||||
titleRes = R.string.ds_bios_dir_not_set
|
||||
messageRes = R.string.ds_bios_dir_not_set_info
|
||||
} else {
|
||||
titleRes = R.string.incorrect_bios_dir
|
||||
messageRes = R.string.ds_incorrect_bios_dir_info
|
||||
}
|
||||
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(titleRes)
|
||||
.setMessage(messageRes)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> dsBiosPickerLauncher.launch(null) }
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setCancelable(true)
|
||||
.show()
|
||||
}
|
||||
ConsoleType.DSi -> {
|
||||
val titleRes: Int
|
||||
val messageRes: Int
|
||||
if (configurationDirStatus == ConfigurationUtils.ConfigurationDirStatus.UNSET) {
|
||||
titleRes = R.string.dsi_bios_dir_not_set
|
||||
messageRes = R.string.dsi_bios_dir_not_set_info
|
||||
} else {
|
||||
titleRes = R.string.incorrect_bios_dir
|
||||
messageRes = R.string.dsi_incorrect_bios_dir_info
|
||||
}
|
||||
|
||||
AlertDialog.Builder(this)
|
||||
.setTitle(titleRes)
|
||||
.setMessage(messageRes)
|
||||
.setPositiveButton(R.string.ok) { _, _ -> dsiBiosPickerLauncher.launch(null) }
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setCancelable(true)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import me.magnum.melonds.domain.model.*
|
||||
import me.magnum.melonds.domain.repositories.RomsRepository
|
||||
import me.magnum.melonds.domain.repositories.SettingsRepository
|
||||
import me.magnum.melonds.extensions.addTo
|
||||
import me.magnum.melonds.utils.ConfigurationUtils
|
||||
import java.text.Normalizer
|
||||
import java.util.*
|
||||
|
||||
@ -116,10 +117,35 @@ class RomListViewModel @ViewModelInject constructor(private val context: Context
|
||||
romsLiveData.value = romsLiveData.value
|
||||
}
|
||||
|
||||
fun getRomTargetConsoleType(rom: Rom): ConsoleType {
|
||||
return rom.config.runtimeConsoleType.targetConsoleType ?: settingsRepository.getDefaultConsoleType()
|
||||
}
|
||||
|
||||
fun getDsConfigurationDirStatus(): ConfigurationUtils.ConfigurationDirStatus {
|
||||
return ConfigurationUtils.checkConfigurationDirectory(context, settingsRepository.getDsBiosDirectory(), ConsoleType.DS)
|
||||
}
|
||||
|
||||
fun getRomConfigurationDirStatus(rom: Rom): ConfigurationUtils.ConfigurationDirStatus {
|
||||
val romTargetConsoleType = getRomTargetConsoleType(rom)
|
||||
val romTargetConfigurationDir = when(romTargetConsoleType) {
|
||||
ConsoleType.DS -> settingsRepository.getDsBiosDirectory()
|
||||
ConsoleType.DSi -> settingsRepository.getDsiBiosDirectory()
|
||||
}
|
||||
return ConfigurationUtils.checkConfigurationDirectory(context, romTargetConfigurationDir, romTargetConsoleType)
|
||||
}
|
||||
|
||||
fun addRomSearchDirectory(directoryUri: Uri) {
|
||||
settingsRepository.addRomSearchDirectory(directoryUri)
|
||||
}
|
||||
|
||||
fun setDsBiosDirectory(uri: Uri) {
|
||||
settingsRepository.setDsBiosDirectory(uri)
|
||||
}
|
||||
|
||||
fun setDsiBiosDirectory(uri: Uri) {
|
||||
settingsRepository.setDsiBiosDirectory(uri)
|
||||
}
|
||||
|
||||
private fun buildAlphabeticalRomComparator(): Comparator<Rom> {
|
||||
return if (sortingOrder == SortingOrder.ASCENDING) {
|
||||
Comparator { o1: Rom, o2: Rom ->
|
||||
|
@ -4,11 +4,14 @@ import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.preference.*
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import me.magnum.melonds.R
|
||||
import me.magnum.melonds.domain.model.ConsoleType
|
||||
import me.magnum.melonds.preferences.DirectoryPickerPreference
|
||||
import me.magnum.melonds.utils.ConfigurationUtils
|
||||
import me.magnum.melonds.utils.DirectoryPickerContract
|
||||
import me.magnum.melonds.utils.FileUtils
|
||||
|
||||
@ -99,15 +102,19 @@ class SettingsActivity : AppCompatActivity() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.pref_main, rootKey)
|
||||
val romDirsPreference = findPreference<DirectoryPickerPreference>("rom_search_dirs")!!
|
||||
val biosDirPreference = findPreference<DirectoryPickerPreference>("bios_dir")!!
|
||||
val consoleTypePreference = findPreference<ListPreference>("console_type")!!
|
||||
val dsBiosDirPreference = findPreference<DirectoryPickerPreference>("bios_dir")!!
|
||||
val dsiBiosDirPreference = findPreference<DirectoryPickerPreference>("dsi_bios_dir")!!
|
||||
val sramDirPreference = findPreference<DirectoryPickerPreference>("sram_dir")!!
|
||||
val jitPreference = findPreference<SwitchPreference>("enable_jit")!!
|
||||
bindPreferenceSummaryToValue(romDirsPreference)
|
||||
bindPreferenceSummaryToValue(biosDirPreference)
|
||||
bindPreferenceSummaryToValue(dsBiosDirPreference)
|
||||
bindPreferenceSummaryToValue(dsiBiosDirPreference)
|
||||
bindPreferenceSummaryToValue(sramDirPreference)
|
||||
|
||||
val romPickerLauncher = registerForActivityResult(DirectoryPickerContract(), romDirsPreference::onDirectoryPicked)
|
||||
val biosPickerLauncher = registerForActivityResult(DirectoryPickerContract(), biosDirPreference::onDirectoryPicked)
|
||||
val dsBiosPickerLauncher = registerForActivityResult(DirectoryPickerContract(), dsBiosDirPreference::onDirectoryPicked)
|
||||
val dsiBiosPickerLauncher = registerForActivityResult(DirectoryPickerContract(), dsiBiosDirPreference::onDirectoryPicked)
|
||||
val sramPickerLauncher = registerForActivityResult(DirectoryPickerContract(), sramDirPreference::onDirectoryPicked)
|
||||
|
||||
if (Build.SUPPORTED_64_BIT_ABIS.isEmpty()) {
|
||||
@ -116,16 +123,42 @@ class SettingsActivity : AppCompatActivity() {
|
||||
jitPreference.setSummary(R.string.jit_not_supported)
|
||||
}
|
||||
|
||||
romDirsPreference.setOnPreferenceClickListener {
|
||||
romPickerLauncher.launch(null)
|
||||
consoleTypePreference.setOnPreferenceChangeListener { _, newValue ->
|
||||
val consoleTypePreferenceValue = newValue as String
|
||||
val newConsoleType = ConsoleType.valueOfIgnoreCase(consoleTypePreferenceValue)
|
||||
val newTypeBiosDir = when(newConsoleType) {
|
||||
ConsoleType.DS -> dsBiosDirPreference.getPersistedStringSet(null)?.firstOrNull()?.let { Uri.parse(it) }
|
||||
ConsoleType.DSi -> dsiBiosDirPreference.getPersistedStringSet(null)?.firstOrNull()?.let { Uri.parse(it) }
|
||||
}
|
||||
|
||||
if (ConfigurationUtils.checkConfigurationDirectory(requireContext(), newTypeBiosDir, newConsoleType) != ConfigurationUtils.ConfigurationDirStatus.VALID) {
|
||||
val textRes = when(newConsoleType) {
|
||||
ConsoleType.DS -> R.string.ds_incorrect_bios_dir_info
|
||||
ConsoleType.DSi -> R.string.dsi_incorrect_bios_dir_info
|
||||
}
|
||||
|
||||
AlertDialog.Builder(requireContext())
|
||||
.setMessage(textRes)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
biosDirPreference.setOnPreferenceClickListener {
|
||||
biosPickerLauncher.launch(null)
|
||||
romDirsPreference.setOnPreferenceClickListener { preference ->
|
||||
romPickerLauncher.launch(preference.getPersistedStringSet(null)?.firstOrNull()?.let { Uri.parse(it) })
|
||||
true
|
||||
}
|
||||
sramDirPreference.setOnPreferenceClickListener {
|
||||
sramPickerLauncher.launch(null)
|
||||
dsBiosDirPreference.setOnPreferenceClickListener { preference ->
|
||||
dsBiosPickerLauncher.launch(preference.getPersistedStringSet(null)?.firstOrNull()?.let { Uri.parse(it) })
|
||||
true
|
||||
}
|
||||
dsiBiosDirPreference.setOnPreferenceClickListener { preference ->
|
||||
dsiBiosPickerLauncher.launch(preference.getPersistedStringSet(null)?.firstOrNull()?.let { Uri.parse(it) })
|
||||
true
|
||||
}
|
||||
sramDirPreference.setOnPreferenceClickListener { preference ->
|
||||
sramPickerLauncher.launch(preference.getPersistedStringSet(null)?.firstOrNull()?.let { Uri.parse(it) })
|
||||
true
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package me.magnum.melonds.utils
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import me.magnum.melonds.domain.model.ConsoleType
|
||||
import me.magnum.melonds.utils.FileUtils.getAbsolutePathFromSAFUri
|
||||
import java.io.File
|
||||
|
||||
@ -12,7 +13,7 @@ object ConfigurationUtils {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun checkConfigurationDirectory(context: Context, configurationDir: Uri?): ConfigurationDirStatus {
|
||||
fun checkConfigurationDirectory(context: Context, configurationDir: Uri?, consoleType: ConsoleType): ConfigurationDirStatus {
|
||||
if (configurationDir == null)
|
||||
return ConfigurationDirStatus.UNSET
|
||||
|
||||
@ -21,13 +22,23 @@ object ConfigurationUtils {
|
||||
if (!dir.isDirectory)
|
||||
return ConfigurationDirStatus.INVALID
|
||||
|
||||
val bios7File = DocumentFile.fromFile(File(dir, "bios7.bin"))
|
||||
val bios9File = DocumentFile.fromFile(File(dir, "bios9.bin"))
|
||||
val firmwareFile = DocumentFile.fromFile(File(dir, "firmware.bin"))
|
||||
val requiredFiles = when(consoleType) {
|
||||
ConsoleType.DS -> listOf(
|
||||
DocumentFile.fromFile(File(dir, "bios7.bin")),
|
||||
DocumentFile.fromFile(File(dir, "bios9.bin")),
|
||||
DocumentFile.fromFile(File(dir, "firmware.bin"))
|
||||
)
|
||||
ConsoleType.DSi -> listOf(
|
||||
DocumentFile.fromFile(File(dir, "bios7.bin")),
|
||||
DocumentFile.fromFile(File(dir, "bios9.bin")),
|
||||
DocumentFile.fromFile(File(dir, "firmware.bin")),
|
||||
DocumentFile.fromFile(File(dir, "nand.bin"))
|
||||
)
|
||||
}
|
||||
|
||||
return if (!bios7File.isFile || !bios9File.isFile || !firmwareFile.isFile)
|
||||
ConfigurationDirStatus.INVALID
|
||||
else
|
||||
return if (requiredFiles.all { it.isFile })
|
||||
ConfigurationDirStatus.VALID
|
||||
else
|
||||
ConfigurationDirStatus.INVALID
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package me.magnum.melonds.utils
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.gson.*
|
||||
import java.lang.reflect.Type
|
||||
import kotlin.jvm.Throws
|
||||
|
||||
|
||||
class UriTypeHierarchyAdapter : JsonDeserializer<Uri?>, JsonSerializer<Uri?> {
|
||||
@Throws(JsonParseException::class)
|
||||
override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): Uri {
|
||||
return Uri.parse(json.asString)
|
||||
}
|
||||
|
||||
override fun serialize(src: Uri?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement {
|
||||
return JsonPrimitive(src.toString())
|
||||
}
|
||||
}
|
@ -1,5 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="console_type_values">
|
||||
<item>ds</item>
|
||||
<item>dsi</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="video_filtering_values">
|
||||
<item>none</item>
|
||||
<item>linear</item>
|
||||
|
@ -23,12 +23,15 @@
|
||||
<string name="action_sort_alphabetically">Alphabetically</string>
|
||||
<string name="action_sort_recently_played">Recently played</string>
|
||||
|
||||
<string name="bios_dir_not_set">BIOS directory not set</string>
|
||||
<string name="bios_dir_not_set_info">BIOS directory is not set. Go to the Settings and select the directory that contains bios7.bin, bios9.bin and firmware.bin</string>
|
||||
<string name="ds_bios_dir_not_set">DS BIOS directory not set</string>
|
||||
<string name="ds_bios_dir_not_set_info">DS BIOS directory is not set. Select the directory that contains bios7.bin, bios9.bin and firmware.bin</string>
|
||||
<string name="dsi_bios_dir_not_set">DSi BIOS directory not set</string>
|
||||
<string name="dsi_bios_dir_not_set_info">DSi BIOS directory is not set. Select the directory that contains bios7.bin, bios9.bin, firmware.bin and nand.bin</string>
|
||||
<string name="incorrect_bios_dir">Incorrect BIOS directory</string>
|
||||
<string name="incorrect_bios_dir_info">The BIOS directory that you specified is not correct. Make sure that the selected directory contains bios7.bin, bios9.bin and firmware.bin</string>
|
||||
<string name="ds_incorrect_bios_dir_info">The BIOS directory for the DS system is not correct. Make sure that the selected directory contains bios7.bin, bios9.bin and firmware.bin</string>
|
||||
<string name="dsi_incorrect_bios_dir_info">The BIOS directory for the DSi system is not correct. Make sure that you select a directory that contains bios7.bin, bios9.bin, firmware.bin and nand.bin</string>
|
||||
<string name="storage_permission_required">Storage permission required</string>
|
||||
<string name="storage_permission_required_info">Storage permission is required to load ROMs on your device. Please grant access to storage on the next dialog.</string>
|
||||
<string name="storage_permission_required_info">Storage permission is required to load ROMs from your device. Please grant access to storage on the next dialog.</string>
|
||||
<string name="no_rom_search_directory_specified">No ROM search directory specified</string>
|
||||
<string name="set_rom_directory">Set ROM directory</string>
|
||||
<string name="info_no_storage_permission">Cannot load ROM without storage permission</string>
|
||||
@ -49,7 +52,9 @@
|
||||
<string name="category_system">System</string>
|
||||
<string name="theme">Theme</string>
|
||||
<string name="rom_search_directories">Search directories</string>
|
||||
<string name="bios_directory">BIOS directory</string>
|
||||
<string name="console_type">Default system</string>
|
||||
<string name="bios_directory">DS BIOS directory</string>
|
||||
<string name="dsi_bios_directory">DSi BIOS directory</string>
|
||||
<string name="show_boot_screen">Show boot screen</string>
|
||||
<string name="enable_jit">Enable JIT</string>
|
||||
<string name="enable_jit_summary">Improves performance but may cause freezes or crashes</string>
|
||||
@ -96,6 +101,11 @@
|
||||
<item>@string/theme_option_dark</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="console_type_options">
|
||||
<item>DS</item>
|
||||
<item>DSi (Experimental)</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="video_filtering_options">
|
||||
<item>None</item>
|
||||
<item>Linear</item>
|
||||
|
@ -27,10 +27,22 @@
|
||||
<PreferenceCategory
|
||||
android:title="@string/category_system">
|
||||
|
||||
<ListPreference
|
||||
android:key="console_type"
|
||||
android:title="@string/console_type"
|
||||
android:summary="%s"
|
||||
android:entries="@array/console_type_options"
|
||||
android:entryValues="@array/console_type_values"
|
||||
android:defaultValue="ds" />
|
||||
|
||||
<me.magnum.melonds.preferences.DirectoryPickerPreference
|
||||
android:key="bios_dir"
|
||||
android:title="@string/bios_directory" />
|
||||
|
||||
<me.magnum.melonds.preferences.DirectoryPickerPreference
|
||||
android:key="dsi_bios_dir"
|
||||
android:title="@string/dsi_bios_directory" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="show_bios"
|
||||
android:title="@string/show_boot_screen"
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d5c53e4292eeef5e4d62c6b5038cfdf0b16c22f0
|
||||
Subproject commit dc127a33d2642c5ea03e2ab02b5a1ed53d5a3f80
|
Loading…
x
Reference in New Issue
Block a user