From 0a3ee936c01483b48c474096a470e83562059007 Mon Sep 17 00:00:00 2001 From: Rafael Caetano Date: Thu, 27 Jun 2024 19:24:26 +0100 Subject: [PATCH] Add support for slot 2 Memory Expansion --- app/src/main/cpp/MelonDSAndroidJNI.cpp | 34 ++- .../java/me/magnum/melonds/MelonEmulator.kt | 12 +- .../CompressedRomFileProcessor.kt | 2 + .../romprocessors/NdsRomFileProcessor.kt | 4 +- .../common/romprocessors/RomFileProcessor.kt | 2 +- .../me/magnum/melonds/di/MigrationModule.kt | 1 + .../magnum/melonds/domain/model/RomConfig.kt | 15 -- .../melonds/domain/model/{ => rom}/Rom.kt | 3 +- .../domain/model/rom/config/RomConfig.kt | 10 + .../model/rom/config/RomGbaSlotConfig.kt | 9 + .../{ => rom/config}/RuntimeConsoleType.kt | 4 +- .../model/{ => rom/config}/RuntimeEnum.kt | 2 +- .../{ => rom/config}/RuntimeMicSource.kt | 4 +- .../domain/repositories/RomsRepository.kt | 4 +- .../repositories/SaveStatesRepository.kt | 3 +- .../domain/repositories/SettingsRepository.kt | 1 + .../domain/services/EmulatorManager.kt | 2 +- .../melonds/impl/FileSystemRomsRepository.kt | 6 +- .../impl/FileSystemSaveStatesRepository.kt | 2 +- .../me/magnum/melonds/impl/NdsRomCache.kt | 2 +- .../me/magnum/melonds/impl/RomIconProvider.kt | 2 +- .../impl/SaveStateScreenshotProvider.kt | 2 +- .../SharedPreferencesSettingsRepository.kt | 2 +- .../impl/dtos/{ => rom}/RomConfigDto.kt | 27 +- .../melonds/impl/dtos/{ => rom}/RomDto.kt | 4 +- .../impl/dtos/rom/RomGbaSlotConfigDto.kt | 51 ++++ .../impl/emulator/AndroidEmulatorManager.kt | 22 +- .../melonds/impl/emulator/EmulatorSession.kt | 2 +- .../melonds/impl/emulator/SramProvider.kt | 2 +- .../melonds/migrations/Migration30to31.kt | 49 ++++ .../melonds/migrations/legacy/RomConfig1.kt | 4 +- .../migrations/legacy/RomConfigDto25.kt | 5 +- .../migrations/legacy/RomConfigDto31.kt | 16 ++ .../melonds/migrations/legacy/RomDto31.kt | 28 +++ .../legacy/RomGbaSlotConfigDto31.kt | 17 ++ .../parcelables/RomConfigParcelable.kt | 27 +- .../parcelables/RomGbaSlotConfigParcelable.kt | 54 ++++ .../melonds/parcelables/RomParcelable.kt | 2 +- .../viewmodel/RetroAchievementsViewModel.kt | 2 +- .../dsiwaremanager/DSiWareRomListViewModel.kt | 2 +- .../model/DSiWareMangerRomListUiState.kt | 2 +- .../ui/dsiwaremanager/ui/DSiWareManager.kt | 2 +- .../dsiwaremanager/ui/DSiWareRomListDialog.kt | 4 +- .../melonds/ui/dsiwaremanager/ui/RomItem.kt | 4 +- .../melonds/ui/emulator/EmulatorActivity.kt | 2 +- .../EmulatorRetroAchievementsViewModel.kt | 2 +- .../melonds/ui/emulator/EmulatorViewModel.kt | 2 +- .../ui/emulator/model/EmulatorState.kt | 2 +- .../ui/romdetails/RomDetailsActivity.kt | 2 +- .../RomDetailsRetroAchievementsViewModel.kt | 2 +- .../ui/romdetails/RomDetailsUiMapper.kt | 22 +- .../ui/romdetails/RomDetailsViewModel.kt | 75 ++++-- .../ui/romdetails/model/RomConfigUiModel.kt | 13 +- .../romdetails/model/RomConfigUpdateEvent.kt | 6 +- .../model/RomGbaSlotConfigUiModel.kt | 12 + .../melonds/ui/romdetails/ui/RomConfigUi.kt | 69 +++--- .../ui/romdetails/ui/RomDetailsScreen.kt | 4 +- .../melonds/ui/romdetails/ui/RomHeaderUi.kt | 4 +- .../melonds/ui/romlist/RomConfigDialog.kt | 222 ----------------- .../melonds/ui/romlist/RomListActivity.kt | 2 +- .../melonds/ui/romlist/RomListFragment.kt | 2 +- .../melonds/ui/romlist/RomListViewModel.kt | 23 +- .../ui/shortcutsetup/ShortcutSetupActivity.kt | 2 +- app/src/main/res/layout/dialog_rom_config.xml | 231 ------------------ app/src/main/res/values-b+es/strings.xml | 1 - app/src/main/res/values-b+fr/strings.xml | 1 - app/src/main/res/values-b+id/strings.xml | 1 - app/src/main/res/values-b+pt+BR/strings.xml | 1 - app/src/main/res/values-b+ru/strings.xml | 1 - app/src/main/res/values/strings.xml | 8 +- buildSrc/src/main/kotlin/AppConfig.kt | 2 +- melonDS-android-lib | 2 +- 72 files changed, 521 insertions(+), 649 deletions(-) delete mode 100644 app/src/main/java/me/magnum/melonds/domain/model/RomConfig.kt rename app/src/main/java/me/magnum/melonds/domain/model/{ => rom}/Rom.kt (80%) create mode 100644 app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomConfig.kt create mode 100644 app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomGbaSlotConfig.kt rename app/src/main/java/me/magnum/melonds/domain/model/{ => rom/config}/RuntimeConsoleType.kt (73%) rename app/src/main/java/me/magnum/melonds/domain/model/{ => rom/config}/RuntimeEnum.kt (60%) rename app/src/main/java/me/magnum/melonds/domain/model/{ => rom/config}/RuntimeMicSource.kt (74%) rename app/src/main/java/me/magnum/melonds/impl/dtos/{ => rom}/RomConfigDto.kt (53%) rename app/src/main/java/me/magnum/melonds/impl/dtos/{ => rom}/RomDto.kt (94%) create mode 100644 app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomGbaSlotConfigDto.kt create mode 100644 app/src/main/java/me/magnum/melonds/migrations/Migration30to31.kt create mode 100644 app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto31.kt create mode 100644 app/src/main/java/me/magnum/melonds/migrations/legacy/RomDto31.kt create mode 100644 app/src/main/java/me/magnum/melonds/migrations/legacy/RomGbaSlotConfigDto31.kt create mode 100644 app/src/main/java/me/magnum/melonds/parcelables/RomGbaSlotConfigParcelable.kt create mode 100644 app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomGbaSlotConfigUiModel.kt delete mode 100644 app/src/main/java/me/magnum/melonds/ui/romlist/RomConfigDialog.kt delete mode 100644 app/src/main/res/layout/dialog_rom_config.xml diff --git a/app/src/main/cpp/MelonDSAndroidJNI.cpp b/app/src/main/cpp/MelonDSAndroidJNI.cpp index 5e35426b..c179adcd 100644 --- a/app/src/main/cpp/MelonDSAndroidJNI.cpp +++ b/app/src/main/cpp/MelonDSAndroidJNI.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include "UriFileHandler.h" @@ -18,7 +19,14 @@ #define MAX_CHEAT_SIZE (2*64) +enum GbaSlotType { + NONE = 0, + GBA_ROM = 1, + MEMORY_EXPANSION = 2, +}; + void* emulate(void*); +MelonDSAndroid::RomGbaSlotConfig* buildGbaSlotConfig(GbaSlotType slotType, const char* romPath, const char* savePath); pthread_t emuThread; pthread_mutex_t emuThreadMutex; @@ -186,7 +194,7 @@ Java_me_magnum_melonds_MelonEmulator_getRichPresenceStatus(JNIEnv* env, jobject } JNIEXPORT jint JNICALL -Java_me_magnum_melonds_MelonEmulator_loadRomInternal(JNIEnv* env, jobject thiz, jstring romPath, jstring sramPath, jboolean loadGbaRom, jstring gbaRomPath, jstring gbaSramPath) +Java_me_magnum_melonds_MelonEmulator_loadRomInternal(JNIEnv* env, jobject thiz, jstring romPath, jstring sramPath, jint gbaSlotType, jstring gbaRomPath, jstring gbaSramPath) { jboolean isCopy = JNI_FALSE; const char* rom = romPath == nullptr ? nullptr : env->GetStringUTFChars(romPath, &isCopy); @@ -194,7 +202,9 @@ Java_me_magnum_melonds_MelonEmulator_loadRomInternal(JNIEnv* env, jobject thiz, const char* gbaRom = gbaRomPath == nullptr ? nullptr : env->GetStringUTFChars(gbaRomPath, &isCopy); const char* gbaSram = gbaSramPath == nullptr ? nullptr : env->GetStringUTFChars(gbaSramPath, &isCopy); - int result = MelonDSAndroid::loadRom(const_cast(rom), const_cast(sram), loadGbaRom, const_cast(gbaRom), const_cast(gbaSram)); + MelonDSAndroid::RomGbaSlotConfig* gbaSlotConfig = buildGbaSlotConfig((GbaSlotType) gbaSlotType, gbaRom, gbaSram); + int result = MelonDSAndroid::loadRom(const_cast(rom), const_cast(sram), gbaSlotConfig); + delete gbaSlotConfig; if (isCopy == JNI_TRUE) { if (romPath) env->ReleaseStringUTFChars(romPath, rom); @@ -467,6 +477,26 @@ Java_me_magnum_melonds_MelonEmulator_updateEmulatorConfiguration(JNIEnv* env, jo } } +MelonDSAndroid::RomGbaSlotConfig* buildGbaSlotConfig(GbaSlotType slotType, const char* romPath, const char* savePath) +{ + if (slotType == GbaSlotType::GBA_ROM) + { + MelonDSAndroid::RomGbaSlotConfigGbaRom* gbaSlotConfigGbaRom = new MelonDSAndroid::RomGbaSlotConfigGbaRom { + .romPath = std::string(romPath), + .savePath = std::string(savePath) + }; + return (MelonDSAndroid::RomGbaSlotConfig*) gbaSlotConfigGbaRom; + } + else if (slotType == GbaSlotType::MEMORY_EXPANSION) + { + return (MelonDSAndroid::RomGbaSlotConfig*) new MelonDSAndroid::RomGbaSlotConfigMemoryExpansion; + } + else + { + return (MelonDSAndroid::RomGbaSlotConfig*) new MelonDSAndroid::RomGbaSlotConfigNone; + } +} + double getCurrentMillis() { timespec now; clock_gettime(CLOCK_REALTIME, &now); diff --git a/app/src/main/java/me/magnum/melonds/MelonEmulator.kt b/app/src/main/java/me/magnum/melonds/MelonEmulator.kt index afa6ccef..f5ea8d1a 100644 --- a/app/src/main/java/me/magnum/melonds/MelonEmulator.kt +++ b/app/src/main/java/me/magnum/melonds/MelonEmulator.kt @@ -37,6 +37,12 @@ object MelonEmulator { DSI_NAND_BAD } + enum class GbaSlotType { + NONE, + GBA_ROM, + MEMORY_EXPANSION, + } + external fun setupEmulator(emulatorConfiguration: EmulatorConfiguration, assetManager: AssetManager?, dsiCameraSource: DSiCameraSource?, retroAchievementsCallback: RetroAchievementsCallback, textureBuffer: ByteBuffer) external fun setupCheats(cheats: Array) @@ -47,8 +53,8 @@ object MelonEmulator { external fun getRichPresenceStatus(): String? - fun loadRom(romUri: Uri, sramUri: Uri, loadGbaRom: Boolean, gbaRomUri: Uri?, gbaSramUri: Uri?): LoadResult { - val loadResult = loadRomInternal(romUri.toString(), sramUri.toString(), loadGbaRom, gbaRomUri?.toString(), gbaSramUri?.toString()) + fun loadRom(romUri: Uri, sramUri: Uri, gbaSlotType: GbaSlotType, gbaRomUri: Uri?, gbaSramUri: Uri?): LoadResult { + val loadResult = loadRomInternal(romUri.toString(), sramUri.toString(), gbaSlotType.ordinal, gbaRomUri?.toString(), gbaSramUri?.toString()) return when (loadResult) { 0 -> LoadResult.SUCCESS 1 -> LoadResult.SUCCESS_GBA_FAILED @@ -63,7 +69,7 @@ object MelonEmulator { return FirmwareLoadResult.entries[loadResult] } - private external fun loadRomInternal(romPath: String, sramPath: String, loadGbaRom: Boolean, gbaRomPath: String?, gbaSramPath: String?): Int + private external fun loadRomInternal(romPath: String, sramPath: String, gbaSlotType: Int, gbaRomPath: String?, gbaSramPath: String?): Int private external fun bootFirmwareInternal(): Int diff --git a/app/src/main/java/me/magnum/melonds/common/romprocessors/CompressedRomFileProcessor.kt b/app/src/main/java/me/magnum/melonds/common/romprocessors/CompressedRomFileProcessor.kt index 3ab90d9b..00fea066 100644 --- a/app/src/main/java/me/magnum/melonds/common/romprocessors/CompressedRomFileProcessor.kt +++ b/app/src/main/java/me/magnum/melonds/common/romprocessors/CompressedRomFileProcessor.kt @@ -6,6 +6,8 @@ import android.net.Uri import io.reactivex.Single import me.magnum.melonds.common.uridelegates.UriHandler import me.magnum.melonds.domain.model.* +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.extensions.isBlank import me.magnum.melonds.extensions.nameWithoutExtension import me.magnum.melonds.impl.NdsRomCache diff --git a/app/src/main/java/me/magnum/melonds/common/romprocessors/NdsRomFileProcessor.kt b/app/src/main/java/me/magnum/melonds/common/romprocessors/NdsRomFileProcessor.kt index 88781c8b..31c19b94 100644 --- a/app/src/main/java/me/magnum/melonds/common/romprocessors/NdsRomFileProcessor.kt +++ b/app/src/main/java/me/magnum/melonds/common/romprocessors/NdsRomFileProcessor.kt @@ -5,8 +5,8 @@ import android.graphics.Bitmap import android.net.Uri import io.reactivex.Single import me.magnum.melonds.common.uridelegates.UriHandler -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.domain.model.RomInfo import me.magnum.melonds.domain.model.RomMetadata import me.magnum.melonds.extensions.isBlank diff --git a/app/src/main/java/me/magnum/melonds/common/romprocessors/RomFileProcessor.kt b/app/src/main/java/me/magnum/melonds/common/romprocessors/RomFileProcessor.kt index d6c3ff6c..e15e9655 100644 --- a/app/src/main/java/me/magnum/melonds/common/romprocessors/RomFileProcessor.kt +++ b/app/src/main/java/me/magnum/melonds/common/romprocessors/RomFileProcessor.kt @@ -3,7 +3,7 @@ package me.magnum.melonds.common.romprocessors import android.graphics.Bitmap import android.net.Uri import io.reactivex.Single -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.RomInfo interface RomFileProcessor { diff --git a/app/src/main/java/me/magnum/melonds/di/MigrationModule.kt b/app/src/main/java/me/magnum/melonds/di/MigrationModule.kt index 8a88bf1f..db2b3b68 100644 --- a/app/src/main/java/me/magnum/melonds/di/MigrationModule.kt +++ b/app/src/main/java/me/magnum/melonds/di/MigrationModule.kt @@ -47,6 +47,7 @@ object MigrationModule { registerMigration(Migration21to22(context, gson, uriHandler)) registerMigration(Migration24to25(genericJsonArrayMigrationHelper, context)) registerMigration(Migration25to26(genericJsonArrayMigrationHelper)) + registerMigration(Migration30to31(genericJsonArrayMigrationHelper)) } } } \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/domain/model/RomConfig.kt b/app/src/main/java/me/magnum/melonds/domain/model/RomConfig.kt deleted file mode 100644 index 2be41074..00000000 --- a/app/src/main/java/me/magnum/melonds/domain/model/RomConfig.kt +++ /dev/null @@ -1,15 +0,0 @@ -package me.magnum.melonds.domain.model - -import android.net.Uri -import java.util.* - -data class RomConfig( - var runtimeConsoleType: RuntimeConsoleType = RuntimeConsoleType.DEFAULT, - var runtimeMicSource: RuntimeMicSource = RuntimeMicSource.DEFAULT, - var layoutId: UUID? = null, - var loadGbaCart: Boolean = false, - var gbaCartPath: Uri? = null, - var gbaSavePath: Uri? = null -) { - fun mustLoadGbaCart() = loadGbaCart && gbaCartPath != null -} \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/domain/model/Rom.kt b/app/src/main/java/me/magnum/melonds/domain/model/rom/Rom.kt similarity index 80% rename from app/src/main/java/me/magnum/melonds/domain/model/Rom.kt rename to app/src/main/java/me/magnum/melonds/domain/model/rom/Rom.kt index 2a6e92a9..fab4d856 100644 --- a/app/src/main/java/me/magnum/melonds/domain/model/Rom.kt +++ b/app/src/main/java/me/magnum/melonds/domain/model/rom/Rom.kt @@ -1,6 +1,7 @@ -package me.magnum.melonds.domain.model +package me.magnum.melonds.domain.model.rom import android.net.Uri +import me.magnum.melonds.domain.model.rom.config.RomConfig import java.util.* data class Rom( diff --git a/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomConfig.kt b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomConfig.kt new file mode 100644 index 00000000..953dc1e0 --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomConfig.kt @@ -0,0 +1,10 @@ +package me.magnum.melonds.domain.model.rom.config + +import java.util.* + +data class RomConfig( + var runtimeConsoleType: RuntimeConsoleType = RuntimeConsoleType.DEFAULT, + var runtimeMicSource: RuntimeMicSource = RuntimeMicSource.DEFAULT, + var layoutId: UUID? = null, + val gbaSlotConfig: RomGbaSlotConfig = RomGbaSlotConfig.None, +) diff --git a/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomGbaSlotConfig.kt b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomGbaSlotConfig.kt new file mode 100644 index 00000000..a252b5f5 --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RomGbaSlotConfig.kt @@ -0,0 +1,9 @@ +package me.magnum.melonds.domain.model.rom.config + +import android.net.Uri + +sealed class RomGbaSlotConfig { + data object None : RomGbaSlotConfig() + data class GbaRom(val romPath: Uri?, val savePath: Uri?) : RomGbaSlotConfig() + data object MemoryExpansion : RomGbaSlotConfig() +} diff --git a/app/src/main/java/me/magnum/melonds/domain/model/RuntimeConsoleType.kt b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeConsoleType.kt similarity index 73% rename from app/src/main/java/me/magnum/melonds/domain/model/RuntimeConsoleType.kt rename to app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeConsoleType.kt index dee46873..68862e56 100644 --- a/app/src/main/java/me/magnum/melonds/domain/model/RuntimeConsoleType.kt +++ b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeConsoleType.kt @@ -1,4 +1,6 @@ -package me.magnum.melonds.domain.model +package me.magnum.melonds.domain.model.rom.config + +import me.magnum.melonds.domain.model.ConsoleType enum class RuntimeConsoleType(val targetConsoleType: ConsoleType?) : RuntimeEnum { DEFAULT(null), diff --git a/app/src/main/java/me/magnum/melonds/domain/model/RuntimeEnum.kt b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeEnum.kt similarity index 60% rename from app/src/main/java/me/magnum/melonds/domain/model/RuntimeEnum.kt rename to app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeEnum.kt index c8bfd37c..adf91fc4 100644 --- a/app/src/main/java/me/magnum/melonds/domain/model/RuntimeEnum.kt +++ b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeEnum.kt @@ -1,4 +1,4 @@ -package me.magnum.melonds.domain.model +package me.magnum.melonds.domain.model.rom.config interface RuntimeEnum { fun getDefault(): T diff --git a/app/src/main/java/me/magnum/melonds/domain/model/RuntimeMicSource.kt b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeMicSource.kt similarity index 74% rename from app/src/main/java/me/magnum/melonds/domain/model/RuntimeMicSource.kt rename to app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeMicSource.kt index a526af38..e7ddd7ec 100644 --- a/app/src/main/java/me/magnum/melonds/domain/model/RuntimeMicSource.kt +++ b/app/src/main/java/me/magnum/melonds/domain/model/rom/config/RuntimeMicSource.kt @@ -1,4 +1,6 @@ -package me.magnum.melonds.domain.model +package me.magnum.melonds.domain.model.rom.config + +import me.magnum.melonds.domain.model.MicSource enum class RuntimeMicSource(val micSource: MicSource?) : RuntimeEnum { DEFAULT(null), diff --git a/app/src/main/java/me/magnum/melonds/domain/repositories/RomsRepository.kt b/app/src/main/java/me/magnum/melonds/domain/repositories/RomsRepository.kt index 06673b66..e604454a 100644 --- a/app/src/main/java/me/magnum/melonds/domain/repositories/RomsRepository.kt +++ b/app/src/main/java/me/magnum/melonds/domain/repositories/RomsRepository.kt @@ -3,8 +3,8 @@ package me.magnum.melonds.domain.repositories import android.net.Uri import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.domain.model.RomScanningStatus import java.util.* diff --git a/app/src/main/java/me/magnum/melonds/domain/repositories/SaveStatesRepository.kt b/app/src/main/java/me/magnum/melonds/domain/repositories/SaveStatesRepository.kt index eb602cb6..4ffcd020 100644 --- a/app/src/main/java/me/magnum/melonds/domain/repositories/SaveStatesRepository.kt +++ b/app/src/main/java/me/magnum/melonds/domain/repositories/SaveStatesRepository.kt @@ -2,8 +2,7 @@ package me.magnum.melonds.domain.repositories import android.graphics.Bitmap import android.net.Uri -import io.reactivex.Single -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.SaveStateSlot interface SaveStatesRepository { diff --git a/app/src/main/java/me/magnum/melonds/domain/repositories/SettingsRepository.kt b/app/src/main/java/me/magnum/melonds/domain/repositories/SettingsRepository.kt index 668ecaca..c0bce840 100644 --- a/app/src/main/java/me/magnum/melonds/domain/repositories/SettingsRepository.kt +++ b/app/src/main/java/me/magnum/melonds/domain/repositories/SettingsRepository.kt @@ -5,6 +5,7 @@ import io.reactivex.Observable import kotlinx.coroutines.flow.Flow import me.magnum.melonds.domain.model.* import me.magnum.melonds.domain.model.camera.DSiCameraSourceType +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.ui.Theme import java.util.* diff --git a/app/src/main/java/me/magnum/melonds/domain/services/EmulatorManager.kt b/app/src/main/java/me/magnum/melonds/domain/services/EmulatorManager.kt index 8bc67805..997799c1 100644 --- a/app/src/main/java/me/magnum/melonds/domain/services/EmulatorManager.kt +++ b/app/src/main/java/me/magnum/melonds/domain/services/EmulatorManager.kt @@ -4,7 +4,7 @@ import android.net.Uri import kotlinx.coroutines.flow.Flow import me.magnum.melonds.domain.model.Cheat import me.magnum.melonds.domain.model.ConsoleType -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.emulator.FirmwareLaunchResult import me.magnum.melonds.domain.model.emulator.RomLaunchResult import me.magnum.melonds.domain.model.retroachievements.GameAchievementData diff --git a/app/src/main/java/me/magnum/melonds/impl/FileSystemRomsRepository.kt b/app/src/main/java/me/magnum/melonds/impl/FileSystemRomsRepository.kt index 2c634148..0ad7d21d 100644 --- a/app/src/main/java/me/magnum/melonds/impl/FileSystemRomsRepository.kt +++ b/app/src/main/java/me/magnum/melonds/impl/FileSystemRomsRepository.kt @@ -13,13 +13,13 @@ import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import me.magnum.melonds.common.romprocessors.RomFileProcessorFactory -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.domain.model.RomScanningStatus import me.magnum.melonds.domain.repositories.RomsRepository import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.extensions.addTo -import me.magnum.melonds.impl.dtos.RomDto +import me.magnum.melonds.impl.dtos.rom.RomDto import me.magnum.melonds.utils.FileUtils import me.magnum.melonds.utils.SubjectSharedFlow import java.io.File diff --git a/app/src/main/java/me/magnum/melonds/impl/FileSystemSaveStatesRepository.kt b/app/src/main/java/me/magnum/melonds/impl/FileSystemSaveStatesRepository.kt index b1985f36..64d397d5 100644 --- a/app/src/main/java/me/magnum/melonds/impl/FileSystemSaveStatesRepository.kt +++ b/app/src/main/java/me/magnum/melonds/impl/FileSystemSaveStatesRepository.kt @@ -4,7 +4,7 @@ import android.graphics.Bitmap import android.net.Uri import androidx.documentfile.provider.DocumentFile import me.magnum.melonds.common.uridelegates.UriHandler -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.SaveStateSlot import me.magnum.melonds.domain.repositories.SaveStatesRepository import me.magnum.melonds.domain.repositories.SettingsRepository diff --git a/app/src/main/java/me/magnum/melonds/impl/NdsRomCache.kt b/app/src/main/java/me/magnum/melonds/impl/NdsRomCache.kt index 4bd57253..a3580068 100644 --- a/app/src/main/java/me/magnum/melonds/impl/NdsRomCache.kt +++ b/app/src/main/java/me/magnum/melonds/impl/NdsRomCache.kt @@ -5,7 +5,7 @@ import android.net.Uri import androidx.documentfile.provider.DocumentFile import io.reactivex.Observable import io.reactivex.subjects.PublishSubject -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.SizeUnit import me.magnum.melonds.domain.repositories.SettingsRepository import java.io.File diff --git a/app/src/main/java/me/magnum/melonds/impl/RomIconProvider.kt b/app/src/main/java/me/magnum/melonds/impl/RomIconProvider.kt index f39a566d..2c74fa72 100644 --- a/app/src/main/java/me/magnum/melonds/impl/RomIconProvider.kt +++ b/app/src/main/java/me/magnum/melonds/impl/RomIconProvider.kt @@ -7,7 +7,7 @@ import androidx.documentfile.provider.DocumentFile import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import me.magnum.melonds.common.romprocessors.RomFileProcessorFactory -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import java.io.File import java.util.* import java.util.concurrent.locks.ReentrantLock diff --git a/app/src/main/java/me/magnum/melonds/impl/SaveStateScreenshotProvider.kt b/app/src/main/java/me/magnum/melonds/impl/SaveStateScreenshotProvider.kt index 4afd47c0..5d04ac48 100644 --- a/app/src/main/java/me/magnum/melonds/impl/SaveStateScreenshotProvider.kt +++ b/app/src/main/java/me/magnum/melonds/impl/SaveStateScreenshotProvider.kt @@ -5,7 +5,7 @@ import android.graphics.Bitmap import android.net.Uri import androidx.documentfile.provider.DocumentFile import com.squareup.picasso.Picasso -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.SaveStateSlot import java.io.File diff --git a/app/src/main/java/me/magnum/melonds/impl/SharedPreferencesSettingsRepository.kt b/app/src/main/java/me/magnum/melonds/impl/SharedPreferencesSettingsRepository.kt index ef7ab126..1ced07ff 100644 --- a/app/src/main/java/me/magnum/melonds/impl/SharedPreferencesSettingsRepository.kt +++ b/app/src/main/java/me/magnum/melonds/impl/SharedPreferencesSettingsRepository.kt @@ -36,7 +36,7 @@ import me.magnum.melonds.domain.model.LayoutConfiguration import me.magnum.melonds.domain.model.MacAddress import me.magnum.melonds.domain.model.MicSource import me.magnum.melonds.domain.model.RendererConfiguration -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.RomIconFiltering import me.magnum.melonds.domain.model.SaveStateLocation import me.magnum.melonds.domain.model.SizeUnit diff --git a/app/src/main/java/me/magnum/melonds/impl/dtos/RomConfigDto.kt b/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomConfigDto.kt similarity index 53% rename from app/src/main/java/me/magnum/melonds/impl/dtos/RomConfigDto.kt rename to app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomConfigDto.kt index 3afbebe0..571eecaf 100644 --- a/app/src/main/java/me/magnum/melonds/impl/dtos/RomConfigDto.kt +++ b/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomConfigDto.kt @@ -1,11 +1,10 @@ -package me.magnum.melonds.impl.dtos +package me.magnum.melonds.impl.dtos.rom -import android.net.Uri import com.google.gson.annotations.SerializedName -import me.magnum.melonds.domain.model.RomConfig -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource -import java.util.* +import me.magnum.melonds.domain.model.rom.config.RomConfig +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource +import java.util.UUID data class RomConfigDto( @SerializedName("runtimeConsoleType") @@ -14,12 +13,8 @@ data class RomConfigDto( val runtimeMicSource: RuntimeMicSource, @SerializedName("layoutId") val layoutId: String?, - @SerializedName("loadGbaCart") - val loadGbaCart: Boolean, - @SerializedName("gbaCartPath") - val gbaCartPath: String?, - @SerializedName("gbaSavePath") - val gbaSavePath: String?, + @SerializedName("gbaSlotConfig") + val gbaSlotConfig: RomGbaSlotConfigDto, ) { companion object { @@ -28,9 +23,7 @@ data class RomConfigDto( romConfig.runtimeConsoleType, romConfig.runtimeMicSource, romConfig.layoutId?.toString(), - romConfig.loadGbaCart, - romConfig.gbaCartPath?.toString(), - romConfig.gbaSavePath?.toString(), + RomGbaSlotConfigDto.fromModel(romConfig.gbaSlotConfig), ) } } @@ -40,9 +33,7 @@ data class RomConfigDto( runtimeConsoleType, runtimeMicSource, layoutId?.let { UUID.fromString(it) }, - loadGbaCart, - gbaCartPath?.let { Uri.parse(it) }, - gbaSavePath?.let { Uri.parse(it) }, + gbaSlotConfig.toModel(), ) } } \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/impl/dtos/RomDto.kt b/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomDto.kt similarity index 94% rename from app/src/main/java/me/magnum/melonds/impl/dtos/RomDto.kt rename to app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomDto.kt index 6ea8e4b0..6240a135 100644 --- a/app/src/main/java/me/magnum/melonds/impl/dtos/RomDto.kt +++ b/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomDto.kt @@ -1,8 +1,8 @@ -package me.magnum.melonds.impl.dtos +package me.magnum.melonds.impl.dtos.rom import android.net.Uri import com.google.gson.annotations.SerializedName -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import java.util.* data class RomDto( diff --git a/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomGbaSlotConfigDto.kt b/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomGbaSlotConfigDto.kt new file mode 100644 index 00000000..f6cb24ef --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/impl/dtos/rom/RomGbaSlotConfigDto.kt @@ -0,0 +1,51 @@ +package me.magnum.melonds.impl.dtos.rom + +import android.net.Uri +import com.google.gson.annotations.SerializedName +import me.magnum.melonds.domain.model.rom.config.RomGbaSlotConfig + +/** + * GBA slot config DTO holds information about all possible configs in a single object. This makes (de)serialization easier since it avoids dealing with polymorphism. + */ +data class RomGbaSlotConfigDto( + @SerializedName("type") + val type: Type, + @SerializedName("gbaRomPath") + val gbaRomPath: String?, + @SerializedName("gbaSavePath") + val gbaSavePath: String?, +) { + + enum class Type { + None, GbaRom, MemoryExpansion + } + + fun toModel(): RomGbaSlotConfig { + return when (type) { + Type.None -> RomGbaSlotConfig.None + Type.GbaRom -> RomGbaSlotConfig.GbaRom( + romPath = gbaRomPath?.let { Uri.parse(it) }, + savePath = gbaSavePath?.let { Uri.parse(it) }, + ) + Type.MemoryExpansion -> RomGbaSlotConfig.MemoryExpansion + } + } + + companion object { + fun fromModel(romGbaSlotConfig: RomGbaSlotConfig): RomGbaSlotConfigDto { + return RomGbaSlotConfigDto( + type = romGbaSlotConfig.dtoType(), + gbaRomPath = (romGbaSlotConfig as? RomGbaSlotConfig.GbaRom)?.romPath?.toString(), + gbaSavePath = (romGbaSlotConfig as? RomGbaSlotConfig.GbaRom)?.savePath?.toString(), + ) + } + + private fun RomGbaSlotConfig.dtoType(): Type { + return when (this) { + is RomGbaSlotConfig.None -> Type.None + is RomGbaSlotConfig.GbaRom -> Type.GbaRom + is RomGbaSlotConfig.MemoryExpansion -> Type.MemoryExpansion + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/impl/emulator/AndroidEmulatorManager.kt b/app/src/main/java/me/magnum/melonds/impl/emulator/AndroidEmulatorManager.kt index 10c8433a..5063f70c 100644 --- a/app/src/main/java/me/magnum/melonds/impl/emulator/AndroidEmulatorManager.kt +++ b/app/src/main/java/me/magnum/melonds/impl/emulator/AndroidEmulatorManager.kt @@ -18,14 +18,15 @@ import me.magnum.melonds.domain.model.Cheat import me.magnum.melonds.domain.model.ConsoleType import me.magnum.melonds.domain.model.EmulatorConfiguration import me.magnum.melonds.domain.model.MicSource -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeEnum +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeEnum import me.magnum.melonds.domain.model.emulator.FirmwareLaunchResult import me.magnum.melonds.domain.model.emulator.RomLaunchResult import me.magnum.melonds.domain.model.retroachievements.GameAchievementData import me.magnum.melonds.domain.model.retroachievements.RAEvent import me.magnum.melonds.domain.model.retroachievements.RASimpleAchievement +import me.magnum.melonds.domain.model.rom.config.RomGbaSlotConfig import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.domain.services.EmulatorManager import me.magnum.melonds.impl.camera.DSiCameraSourceMultiplexer @@ -60,7 +61,20 @@ class AndroidEmulatorManager( return@withContext RomLaunchResult.LaunchFailedSramProblem(exception) } - val loadResult = MelonEmulator.loadRom(romUri, sram, rom.config.mustLoadGbaCart(), rom.config.gbaCartPath, rom.config.gbaSavePath) + val gbaSlotRomConfig = rom.config.gbaSlotConfig + val gbaSlotType = when (gbaSlotRomConfig) { + RomGbaSlotConfig.None -> MelonEmulator.GbaSlotType.NONE + is RomGbaSlotConfig.GbaRom -> MelonEmulator.GbaSlotType.GBA_ROM + RomGbaSlotConfig.MemoryExpansion -> MelonEmulator.GbaSlotType.MEMORY_EXPANSION + } + + val loadResult = MelonEmulator.loadRom( + romUri = romUri, + sramUri = sram, + gbaSlotType = gbaSlotType, + gbaRomUri = (gbaSlotRomConfig as? RomGbaSlotConfig.GbaRom)?.romPath, + gbaSramUri = (gbaSlotRomConfig as? RomGbaSlotConfig.GbaRom)?.savePath + ) if (loadResult.isTerminal || !isActive) { cameraManager.stopCurrentCameraSource() RomLaunchResult.LaunchFailed(loadResult) diff --git a/app/src/main/java/me/magnum/melonds/impl/emulator/EmulatorSession.kt b/app/src/main/java/me/magnum/melonds/impl/emulator/EmulatorSession.kt index a65a54eb..1c9d0fee 100644 --- a/app/src/main/java/me/magnum/melonds/impl/emulator/EmulatorSession.kt +++ b/app/src/main/java/me/magnum/melonds/impl/emulator/EmulatorSession.kt @@ -1,7 +1,7 @@ package me.magnum.melonds.impl.emulator import me.magnum.melonds.domain.model.ConsoleType -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.emulator.EmulatorSessionUpdateAction import me.magnum.melonds.domain.model.retroachievements.GameAchievementData diff --git a/app/src/main/java/me/magnum/melonds/impl/emulator/SramProvider.kt b/app/src/main/java/me/magnum/melonds/impl/emulator/SramProvider.kt index d900f0e7..69cd5234 100644 --- a/app/src/main/java/me/magnum/melonds/impl/emulator/SramProvider.kt +++ b/app/src/main/java/me/magnum/melonds/impl/emulator/SramProvider.kt @@ -2,7 +2,7 @@ package me.magnum.melonds.impl.emulator import android.net.Uri import me.magnum.melonds.common.uridelegates.UriHandler -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.repositories.SettingsRepository class SramProvider( diff --git a/app/src/main/java/me/magnum/melonds/migrations/Migration30to31.kt b/app/src/main/java/me/magnum/melonds/migrations/Migration30to31.kt new file mode 100644 index 00000000..99112f13 --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/migrations/Migration30to31.kt @@ -0,0 +1,49 @@ +package me.magnum.melonds.migrations + +import me.magnum.melonds.migrations.helper.GenericJsonArrayMigrationHelper +import me.magnum.melonds.migrations.legacy.RomConfigDto25 +import me.magnum.melonds.migrations.legacy.RomConfigDto31 +import me.magnum.melonds.migrations.legacy.RomDto25 +import me.magnum.melonds.migrations.legacy.RomDto31 +import me.magnum.melonds.migrations.legacy.RomGbaSlotConfigDto31 + +class Migration30to31( + private val romMigrationHelper: GenericJsonArrayMigrationHelper, +) : Migration { + + override val from = 30 + override val to = 31 + + override fun migrate() { + romMigrationHelper.migrateJsonArrayData(ROM_DATA_FILE, RomDto25::class.java) { + RomDto31( + it.name, + it.developerName, + it.fileName, + it.uri, + it.parentTreeUri, + RomConfigDto31( + it.config.runtimeConsoleType, + it.config.runtimeMicSource, + it.config.layoutId, + createGbaSlotConfigDto(it.config), + ), + it.lastPlayed, + it.isDsiWareTitle, + it.retroAchievementsHash, + ) + } + } + + private fun createGbaSlotConfigDto(oldConfig: RomConfigDto25): RomGbaSlotConfigDto31 { + return RomGbaSlotConfigDto31( + type = if (oldConfig.loadGbaCart) RomGbaSlotConfigDto31.Type.GbaRom else RomGbaSlotConfigDto31.Type.None, + gbaRomPath = oldConfig.gbaCartPath, + gbaSavePath = oldConfig.gbaSavePath, + ) + } + + companion object { + private const val ROM_DATA_FILE = "rom_data.json" + } +} \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfig1.kt b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfig1.kt index c4ece3ec..cdaab3cf 100644 --- a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfig1.kt +++ b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfig1.kt @@ -2,8 +2,8 @@ package me.magnum.melonds.migrations.legacy import android.net.Uri import com.google.gson.annotations.SerializedName -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource import java.util.* data class RomConfig1( diff --git a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto25.kt b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto25.kt index 58063b6a..89377154 100644 --- a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto25.kt +++ b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto25.kt @@ -1,9 +1,8 @@ package me.magnum.melonds.migrations.legacy import com.google.gson.annotations.SerializedName -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource -import java.util.* +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource data class RomConfigDto25( @SerializedName("runtimeConsoleType") diff --git a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto31.kt b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto31.kt new file mode 100644 index 00000000..ec448395 --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomConfigDto31.kt @@ -0,0 +1,16 @@ +package me.magnum.melonds.migrations.legacy + +import com.google.gson.annotations.SerializedName +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource + +data class RomConfigDto31( + @SerializedName("runtimeConsoleType") + val runtimeConsoleType: RuntimeConsoleType, + @SerializedName("runtimeMicSource") + val runtimeMicSource: RuntimeMicSource, + @SerializedName("layoutId") + val layoutId: String?, + @SerializedName("gbaSlotConfig") + val gbaSlotConfig: RomGbaSlotConfigDto31, +) \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomDto31.kt b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomDto31.kt new file mode 100644 index 00000000..fdb08725 --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomDto31.kt @@ -0,0 +1,28 @@ +package me.magnum.melonds.migrations.legacy + +import com.google.gson.annotations.SerializedName +import java.util.Date + +/** + * ROM DTO used from app version 27. + */ +data class RomDto31( + @SerializedName("name") + val name: String, + @SerializedName("developerName") + val developerName: String, + @SerializedName("fileName") + val fileName: String, + @SerializedName("uri") + val uri: String, + @SerializedName("parentTreeUri") + val parentTreeUri: String, + @SerializedName("config") + var config: RomConfigDto31, + @SerializedName("lastPlayed") + var lastPlayed: Date? = null, + @SerializedName("isDsiWareTitle") + val isDsiWareTitle: Boolean, + @SerializedName("retroAchievementsHash") + val retroAchievementsHash: String, +) \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/migrations/legacy/RomGbaSlotConfigDto31.kt b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomGbaSlotConfigDto31.kt new file mode 100644 index 00000000..7a1df0c5 --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/migrations/legacy/RomGbaSlotConfigDto31.kt @@ -0,0 +1,17 @@ +package me.magnum.melonds.migrations.legacy + +import com.google.gson.annotations.SerializedName + +class RomGbaSlotConfigDto31( + @SerializedName("type") + val type: Type, + @SerializedName("gbaRomPath") + val gbaRomPath: String?, + @SerializedName("gbaSavePath") + val gbaSavePath: String?, +) { + + enum class Type { + None, GbaRom, MemoryExpansion + } +} diff --git a/app/src/main/java/me/magnum/melonds/parcelables/RomConfigParcelable.kt b/app/src/main/java/me/magnum/melonds/parcelables/RomConfigParcelable.kt index b1e02916..cd2aab8a 100644 --- a/app/src/main/java/me/magnum/melonds/parcelables/RomConfigParcelable.kt +++ b/app/src/main/java/me/magnum/melonds/parcelables/RomConfigParcelable.kt @@ -2,11 +2,11 @@ package me.magnum.melonds.parcelables import android.os.Parcel import android.os.Parcelable -import androidx.core.net.toUri -import me.magnum.melonds.domain.model.RomConfig -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource -import java.util.* +import me.magnum.melonds.domain.model.rom.config.RomConfig +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource +import me.magnum.melonds.extensions.parcelable +import java.util.UUID class RomConfigParcelable : Parcelable { val romConfig: RomConfig @@ -16,22 +16,19 @@ class RomConfigParcelable : Parcelable { } private constructor(parcel: Parcel) { - romConfig = RomConfig() - romConfig.runtimeConsoleType = RuntimeConsoleType.entries[parcel.readInt()] - romConfig.runtimeMicSource = RuntimeMicSource.entries[parcel.readInt()] - romConfig.layoutId = parcel.readString()?.let { UUID.fromString(it) } - romConfig.loadGbaCart = parcel.readInt() == 1 - romConfig.gbaCartPath = parcel.readString()?.toUri() - romConfig.gbaSavePath = parcel.readString()?.toUri() + romConfig = RomConfig( + runtimeConsoleType = RuntimeConsoleType.entries[parcel.readInt()], + runtimeMicSource = RuntimeMicSource.entries[parcel.readInt()], + layoutId = parcel.readString()?.let { UUID.fromString(it) }, + gbaSlotConfig = parcel.parcelable()!!.gbaSlotConfig, + ) } override fun writeToParcel(dest: Parcel, flags: Int) { dest.writeInt(romConfig.runtimeConsoleType.ordinal) dest.writeInt(romConfig.runtimeMicSource.ordinal) dest.writeString(romConfig.layoutId?.toString()) - dest.writeInt(if (romConfig.loadGbaCart) 1 else 0) - dest.writeString(romConfig.gbaCartPath?.toString()) - dest.writeString(romConfig.gbaSavePath?.toString()) + dest.writeParcelable(RomGbaSlotConfigParcelable(romConfig.gbaSlotConfig), 0) } override fun describeContents(): Int { diff --git a/app/src/main/java/me/magnum/melonds/parcelables/RomGbaSlotConfigParcelable.kt b/app/src/main/java/me/magnum/melonds/parcelables/RomGbaSlotConfigParcelable.kt new file mode 100644 index 00000000..5adab0ea --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/parcelables/RomGbaSlotConfigParcelable.kt @@ -0,0 +1,54 @@ +package me.magnum.melonds.parcelables + +import android.os.Parcel +import android.os.Parcelable +import androidx.core.net.toUri +import me.magnum.melonds.domain.model.rom.config.RomGbaSlotConfig + +class RomGbaSlotConfigParcelable : Parcelable { + val gbaSlotConfig: RomGbaSlotConfig + + constructor(gbaSlotConfig: RomGbaSlotConfig) { + this.gbaSlotConfig = gbaSlotConfig + } + + private constructor(parcel: Parcel) { + val type = parcel.readInt() + gbaSlotConfig = when (type) { + TYPE_NONE -> RomGbaSlotConfig.None + TYPE_GBA_ROM -> RomGbaSlotConfig.GbaRom(parcel.readString()?.toUri(), parcel.readString()?.toUri()) + TYPE_MEMORY_EXPANSION -> RomGbaSlotConfig.MemoryExpansion + else -> throw UnsupportedOperationException("Unsupported GBA slot type: $type") + } + } + + override fun writeToParcel(parcel: Parcel, flags: Int) { + when (gbaSlotConfig) { + is RomGbaSlotConfig.None -> parcel.writeInt(TYPE_NONE) + is RomGbaSlotConfig.GbaRom -> { + parcel.writeInt(TYPE_GBA_ROM) + parcel.writeString(gbaSlotConfig.romPath?.toString()) + parcel.writeString(gbaSlotConfig.savePath?.toString()) + } + is RomGbaSlotConfig.MemoryExpansion -> parcel.writeInt(TYPE_MEMORY_EXPANSION) + } + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + private const val TYPE_NONE = 0 + private const val TYPE_GBA_ROM = 1 + private const val TYPE_MEMORY_EXPANSION = 2 + + override fun createFromParcel(parcel: Parcel): RomGbaSlotConfigParcelable { + return RomGbaSlotConfigParcelable(parcel) + } + + override fun newArray(size: Int): Array { + return arrayOfNulls(size) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/parcelables/RomParcelable.kt b/app/src/main/java/me/magnum/melonds/parcelables/RomParcelable.kt index 015e227c..0ac0861f 100644 --- a/app/src/main/java/me/magnum/melonds/parcelables/RomParcelable.kt +++ b/app/src/main/java/me/magnum/melonds/parcelables/RomParcelable.kt @@ -3,7 +3,7 @@ package me.magnum.melonds.parcelables import android.os.Parcel import android.os.Parcelable import androidx.core.net.toUri -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.extensions.parcelable import java.util.* diff --git a/app/src/main/java/me/magnum/melonds/ui/common/viewmodel/RetroAchievementsViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/common/viewmodel/RetroAchievementsViewModel.kt index cd83364e..4a2b7470 100644 --- a/app/src/main/java/me/magnum/melonds/ui/common/viewmodel/RetroAchievementsViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/common/viewmodel/RetroAchievementsViewModel.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.retroachievements.RAUserAchievement import me.magnum.melonds.domain.repositories.RetroAchievementsRepository import me.magnum.melonds.domain.repositories.SettingsRepository diff --git a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/DSiWareRomListViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/DSiWareRomListViewModel.kt index dd44350b..f0ca5b3e 100644 --- a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/DSiWareRomListViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/DSiWareRomListViewModel.kt @@ -4,7 +4,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.* -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.repositories.RomsRepository import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.impl.RomIconProvider diff --git a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/model/DSiWareMangerRomListUiState.kt b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/model/DSiWareMangerRomListUiState.kt index 2efc77a0..017d440f 100644 --- a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/model/DSiWareMangerRomListUiState.kt +++ b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/model/DSiWareMangerRomListUiState.kt @@ -1,6 +1,6 @@ package me.magnum.melonds.ui.dsiwaremanager.model -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom sealed class DSiWareMangerRomListUiState { object Loading : DSiWareMangerRomListUiState() diff --git a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareManager.kt b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareManager.kt index 8c3d6eec..e4f35b8c 100644 --- a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareManager.kt +++ b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareManager.kt @@ -41,7 +41,7 @@ import me.magnum.melonds.common.Permission import me.magnum.melonds.common.contracts.FilePickerContract import me.magnum.melonds.domain.model.ConfigurationDirResult import me.magnum.melonds.domain.model.DSiWareTitle -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.RomIconFiltering import me.magnum.melonds.domain.model.dsinand.DSiWareTitleFileType import me.magnum.melonds.ui.common.FabActionItem diff --git a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareRomListDialog.kt b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareRomListDialog.kt index a7b308db..b3c03535 100644 --- a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareRomListDialog.kt +++ b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/DSiWareRomListDialog.kt @@ -43,8 +43,8 @@ import androidx.core.graphics.createBitmap import androidx.core.graphics.set import androidx.lifecycle.viewmodel.compose.viewModel import me.magnum.melonds.R -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.domain.model.RomIconFiltering import me.magnum.melonds.ui.common.FullScreen import me.magnum.melonds.ui.dsiwaremanager.DSiWareRomListViewModel diff --git a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/RomItem.kt b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/RomItem.kt index 71335e31..5d575162 100644 --- a/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/RomItem.kt +++ b/app/src/main/java/me/magnum/melonds/ui/dsiwaremanager/ui/RomItem.kt @@ -24,8 +24,8 @@ import androidx.compose.ui.unit.sp import androidx.core.graphics.createBitmap import androidx.core.graphics.set import me.magnum.melonds.R -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.domain.model.RomIconFiltering import me.magnum.melonds.ui.common.component.text.CaptionText import me.magnum.melonds.ui.romlist.RomIcon diff --git a/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorActivity.kt b/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorActivity.kt index 6f099436..d5ee7a66 100644 --- a/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorActivity.kt +++ b/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorActivity.kt @@ -69,7 +69,7 @@ import me.magnum.melonds.domain.model.ConsoleType import me.magnum.melonds.domain.model.FpsCounterPosition import me.magnum.melonds.domain.model.LayoutComponent import me.magnum.melonds.domain.model.Orientation -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.SaveStateSlot import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.extensions.insetsControllerCompat diff --git a/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorRetroAchievementsViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorRetroAchievementsViewModel.kt index 957694f2..b01811ae 100644 --- a/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorRetroAchievementsViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorRetroAchievementsViewModel.kt @@ -1,7 +1,7 @@ package me.magnum.melonds.ui.emulator import dagger.hilt.android.lifecycle.HiltViewModel -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.repositories.RetroAchievementsRepository import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.impl.emulator.EmulatorSession diff --git a/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorViewModel.kt index d362d376..83157f61 100644 --- a/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/emulator/EmulatorViewModel.kt @@ -41,7 +41,7 @@ import me.magnum.melonds.domain.model.ConsoleType import me.magnum.melonds.domain.model.FpsCounterPosition import me.magnum.melonds.domain.model.LayoutConfiguration import me.magnum.melonds.domain.model.Orientation -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.RomInfo import me.magnum.melonds.domain.model.RuntimeBackground import me.magnum.melonds.domain.model.SaveStateSlot diff --git a/app/src/main/java/me/magnum/melonds/ui/emulator/model/EmulatorState.kt b/app/src/main/java/me/magnum/melonds/ui/emulator/model/EmulatorState.kt index 3004d74b..4b552495 100644 --- a/app/src/main/java/me/magnum/melonds/ui/emulator/model/EmulatorState.kt +++ b/app/src/main/java/me/magnum/melonds/ui/emulator/model/EmulatorState.kt @@ -2,7 +2,7 @@ package me.magnum.melonds.ui.emulator.model import me.magnum.melonds.MelonEmulator import me.magnum.melonds.domain.model.ConsoleType -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom sealed class EmulatorState { data object Uninitialized : EmulatorState() diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsActivity.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsActivity.kt index c61090ef..19050ebc 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsActivity.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsActivity.kt @@ -34,7 +34,7 @@ class RomDetailsActivity : AppCompatActivity() { val romRetroAchievementsViewModel by viewModels() val rom by romDetailsViewModel.rom.collectAsState() - val romConfig by romDetailsViewModel.romConfig.collectAsState() + val romConfig by romDetailsViewModel.romConfigUiState.collectAsState() val retroAchievementsUiState by romRetroAchievementsViewModel.uiState.collectAsState() diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsRetroAchievementsViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsRetroAchievementsViewModel.kt index fc9b4b35..a48ff467 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsRetroAchievementsViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsRetroAchievementsViewModel.kt @@ -2,7 +2,7 @@ package me.magnum.melonds.ui.romdetails import androidx.lifecycle.SavedStateHandle import dagger.hilt.android.lifecycle.HiltViewModel -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.repositories.RetroAchievementsRepository import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.parcelables.RomParcelable diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsUiMapper.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsUiMapper.kt index 64160cfa..60b08130 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsUiMapper.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsUiMapper.kt @@ -1,11 +1,13 @@ package me.magnum.melonds.ui.romdetails import android.content.Context +import androidx.documentfile.provider.DocumentFile import kotlinx.coroutines.rx2.awaitSingleOrNull -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.config.RomConfig +import me.magnum.melonds.domain.model.rom.config.RomGbaSlotConfig import me.magnum.melonds.domain.repositories.LayoutsRepository import me.magnum.melonds.ui.romdetails.model.RomConfigUiModel -import me.magnum.melonds.utils.FileUtils +import me.magnum.melonds.ui.romdetails.model.RomGbaSlotConfigUiModel class RomDetailsUiMapper( private val context: Context, @@ -18,9 +20,19 @@ class RomDetailsUiMapper( runtimeMicSource = romConfig.runtimeMicSource, layoutId = romConfig.layoutId, layoutName = romConfig.layoutId?.let { layoutsRepository.getLayout(it).awaitSingleOrNull()?.name } ?: layoutsRepository.getGlobalLayoutPlaceholder().name, - loadGbaCart = romConfig.loadGbaCart, - gbaCartPath = FileUtils.getAbsolutePathFromSAFUri(context, romConfig.gbaCartPath), - gbaSavePath = FileUtils.getAbsolutePathFromSAFUri(context, romConfig.gbaSavePath), + gbaSlotConfig = mapGbaSlotConfigToUi(romConfig.gbaSlotConfig), ) } + + private fun mapGbaSlotConfigToUi(gbaSlotConfig: RomGbaSlotConfig): RomGbaSlotConfigUiModel { + return when (gbaSlotConfig) { + is RomGbaSlotConfig.None -> RomGbaSlotConfigUiModel(type = RomGbaSlotConfigUiModel.Type.None) + is RomGbaSlotConfig.GbaRom -> RomGbaSlotConfigUiModel( + type = RomGbaSlotConfigUiModel.Type.GbaRom, + gbaRomPath = gbaSlotConfig.romPath?.let { DocumentFile.fromSingleUri(context, it)?.name }, + gbaSavePath = gbaSlotConfig.savePath?.let { DocumentFile.fromSingleUri(context, it)?.name }, + ) + is RomGbaSlotConfig.MemoryExpansion -> RomGbaSlotConfigUiModel(type = RomGbaSlotConfigUiModel.Type.MemoryExpansion) + } + } } diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsViewModel.kt index cac9eacc..bc0d65b2 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/RomDetailsViewModel.kt @@ -6,18 +6,20 @@ import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import me.magnum.melonds.common.Permission import me.magnum.melonds.common.UriPermissionManager -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig +import me.magnum.melonds.domain.model.rom.config.RomGbaSlotConfig import me.magnum.melonds.domain.repositories.RomsRepository import me.magnum.melonds.domain.repositories.SettingsRepository import me.magnum.melonds.impl.RomIconProvider import me.magnum.melonds.parcelables.RomParcelable import me.magnum.melonds.ui.romdetails.model.RomConfigUiState import me.magnum.melonds.ui.romdetails.model.RomConfigUpdateEvent +import me.magnum.melonds.ui.romdetails.model.RomGbaSlotConfigUiModel import me.magnum.melonds.ui.romlist.RomIcon import javax.inject.Inject @@ -34,25 +36,51 @@ class RomDetailsViewModel @Inject constructor( private val _rom = MutableStateFlow(savedStateHandle.get(RomDetailsActivity.KEY_ROM)!!.rom) val rom = _rom.asStateFlow() - private val _romConfig = MutableStateFlow(RomConfigUiState.Loading) - val romConfig by lazy { - updateRomConfigState() - _romConfig.asStateFlow() + private val _romConfig = MutableStateFlow(_rom.value.config) + + val romConfigUiState by lazy { + val uiStateFlow = MutableStateFlow(RomConfigUiState.Loading) + viewModelScope.launch { + _romConfig.map { + romDetailsUiMapper.mapRomConfigToUi(it) + }.collect { + uiStateFlow.value = RomConfigUiState.Ready(it) + } + } + + uiStateFlow.asStateFlow() } fun onRomConfigUpdateEvent(event: RomConfigUpdateEvent) { - val newConfig = when(event) { - is RomConfigUpdateEvent.RuntimeConsoleUpdate -> _rom.value.config.copy(runtimeConsoleType = event.newRuntimeConsole) - is RomConfigUpdateEvent.RuntimeMicSourceUpdate -> _rom.value.config.copy(runtimeMicSource = event.newRuntimeMicSource) - is RomConfigUpdateEvent.LayoutUpdate -> _rom.value.config.copy(layoutId = event.newLayoutId) - is RomConfigUpdateEvent.LoadGbaRomUpdate -> _rom.value.config.copy(loadGbaCart = event.shouldLoadRom) - is RomConfigUpdateEvent.GbaRomPathUpdate -> _rom.value.config.copy(gbaCartPath = event.gbaRomPath) - is RomConfigUpdateEvent.GbaSavePathUpdate -> _rom.value.config.copy(gbaSavePath = event.gbaSavePath) + val currentRomConfig = _romConfig.value + val newRomConfigUiModel = when(event) { + is RomConfigUpdateEvent.RuntimeConsoleUpdate -> currentRomConfig.copy(runtimeConsoleType = event.newRuntimeConsole) + is RomConfigUpdateEvent.RuntimeMicSourceUpdate -> currentRomConfig.copy(runtimeMicSource = event.newRuntimeMicSource) + is RomConfigUpdateEvent.LayoutUpdate -> currentRomConfig.copy(layoutId = event.newLayoutId) + is RomConfigUpdateEvent.GbaSlotTypeUpdated -> currentRomConfig.let { + val newGbaSlotConfig = when (event.type) { + RomGbaSlotConfigUiModel.Type.None -> RomGbaSlotConfig.None + RomGbaSlotConfigUiModel.Type.GbaRom -> RomGbaSlotConfig.GbaRom(null, null) + RomGbaSlotConfigUiModel.Type.MemoryExpansion -> RomGbaSlotConfig.MemoryExpansion + } + it.copy(gbaSlotConfig = newGbaSlotConfig) + } + is RomConfigUpdateEvent.GbaRomPathUpdate -> currentRomConfig.let { + (currentRomConfig.gbaSlotConfig as? RomGbaSlotConfig.GbaRom)?.let { gbaConfig -> + it.copy(gbaSlotConfig = gbaConfig.copy(romPath = event.gbaRomPath)) + } + } + is RomConfigUpdateEvent.GbaSavePathUpdate -> currentRomConfig.let { + (currentRomConfig.gbaSlotConfig as? RomGbaSlotConfig.GbaRom)?.let { gbaConfig -> + it.copy(gbaSlotConfig = gbaConfig.copy(savePath = event.gbaSavePath)) + } + } } - _rom.update { it.copy(config = newConfig) } - saveRomConfig(newConfig) - updateRomConfigState() + newRomConfigUiModel?.let { + _romConfig.value = it + saveRomConfig(it) + } } suspend fun getRomIcon(rom: Rom): RomIcon { @@ -61,16 +89,11 @@ class RomDetailsViewModel @Inject constructor( return RomIcon(romIconBitmap, iconFiltering) } - private fun updateRomConfigState() { - viewModelScope.launch { - val romConfigUiModel = romDetailsUiMapper.mapRomConfigToUi(_rom.value.config) - _romConfig.value = RomConfigUiState.Ready(romConfigUiModel) - } - } - private fun saveRomConfig(newConfig: RomConfig) { - newConfig.gbaCartPath?.let { uriPermissionManager.persistFilePermissions(it, Permission.READ) } - newConfig.gbaSavePath?.let { uriPermissionManager.persistFilePermissions(it, Permission.READ_WRITE) } + if (newConfig.gbaSlotConfig is RomGbaSlotConfig.GbaRom) { + newConfig.gbaSlotConfig.romPath?.let { uriPermissionManager.persistFilePermissions(it, Permission.READ) } + newConfig.gbaSlotConfig.savePath?.let { uriPermissionManager.persistFilePermissions(it, Permission.READ_WRITE) } + } romsRepository.updateRomConfig(_rom.value, newConfig) } } \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUiModel.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUiModel.kt index aac93058..4289c901 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUiModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUiModel.kt @@ -1,18 +1,13 @@ package me.magnum.melonds.ui.romdetails.model -import android.net.Uri -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource -import java.util.* +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource +import java.util.UUID data class RomConfigUiModel( val runtimeConsoleType: RuntimeConsoleType = RuntimeConsoleType.DEFAULT, val runtimeMicSource: RuntimeMicSource = RuntimeMicSource.DEFAULT, val layoutId: UUID? = null, val layoutName: String? = null, - val loadGbaCart: Boolean = false, - val gbaCartPath: String? = null, - val gbaCartUri: Uri? = null, - val gbaSavePath: String? = null, - val gbaSaveUri: Uri? = null, + val gbaSlotConfig: RomGbaSlotConfigUiModel = RomGbaSlotConfigUiModel() ) diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUpdateEvent.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUpdateEvent.kt index 87f91091..409e1c95 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUpdateEvent.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomConfigUpdateEvent.kt @@ -1,15 +1,15 @@ package me.magnum.melonds.ui.romdetails.model import android.net.Uri -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource import java.util.UUID sealed class RomConfigUpdateEvent { data class RuntimeConsoleUpdate(val newRuntimeConsole: RuntimeConsoleType) : RomConfigUpdateEvent() data class RuntimeMicSourceUpdate(val newRuntimeMicSource: RuntimeMicSource) : RomConfigUpdateEvent() data class LayoutUpdate(val newLayoutId: UUID?) : RomConfigUpdateEvent() - data class LoadGbaRomUpdate(val shouldLoadRom: Boolean) : RomConfigUpdateEvent() + data class GbaSlotTypeUpdated(val type: RomGbaSlotConfigUiModel.Type) : RomConfigUpdateEvent() data class GbaRomPathUpdate(val gbaRomPath: Uri?) : RomConfigUpdateEvent() data class GbaSavePathUpdate(val gbaSavePath: Uri?) : RomConfigUpdateEvent() } diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomGbaSlotConfigUiModel.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomGbaSlotConfigUiModel.kt new file mode 100644 index 00000000..508d48cd --- /dev/null +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/model/RomGbaSlotConfigUiModel.kt @@ -0,0 +1,12 @@ +package me.magnum.melonds.ui.romdetails.model + +data class RomGbaSlotConfigUiModel( + val type: Type = Type.None, + val gbaRomPath: String? = null, + val gbaSavePath: String? = null, +) { + + enum class Type { + None, GbaRom, MemoryExpansion + } +} diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomConfigUi.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomConfigUi.kt index 5a6c0479..39df5c01 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomConfigUi.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomConfigUi.kt @@ -4,10 +4,14 @@ import android.app.Activity import android.content.Intent import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.layout.* +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll -import androidx.compose.material.* +import androidx.compose.material.CircularProgressIndicator +import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -17,18 +21,18 @@ import androidx.compose.ui.res.stringResource import me.magnum.melonds.R import me.magnum.melonds.common.Permission import me.magnum.melonds.common.contracts.FilePickerContract -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType +import me.magnum.melonds.domain.model.rom.config.RuntimeMicSource import me.magnum.melonds.ui.common.MelonPreviewSet import me.magnum.melonds.ui.common.preference.ActionLauncherItem import me.magnum.melonds.ui.common.preference.SingleChoiceItem -import me.magnum.melonds.ui.common.preference.SwitchItem import me.magnum.melonds.ui.layouts.LayoutSelectorActivity import me.magnum.melonds.ui.romdetails.model.RomConfigUiModel import me.magnum.melonds.ui.romdetails.model.RomConfigUiState import me.magnum.melonds.ui.romdetails.model.RomConfigUpdateEvent +import me.magnum.melonds.ui.romdetails.model.RomGbaSlotConfigUiModel import me.magnum.melonds.ui.theme.MelonTheme -import java.util.* +import java.util.UUID @Composable fun RomConfigUi( @@ -105,12 +109,15 @@ private fun Content( } ) - SwitchItem( - name = stringResource(id = R.string.label_rom_config_load_gba_rom), - isOn = romConfig.loadGbaCart, - onToggle = { - onConfigUpdate(RomConfigUpdateEvent.LoadGbaRomUpdate(it)) - }, + val gbaSlotOptions = stringArrayResource(id = R.array.gba_slot_options) + SingleChoiceItem( + name = stringResource(id = R.string.label_rom_config_gba_slot), + value = gbaSlotOptions[romConfig.gbaSlotConfig.type.ordinal], + items = gbaSlotOptions.toList(), + selectedItemIndex = romConfig.gbaSlotConfig.type.ordinal, + onItemSelected = { + onConfigUpdate(RomConfigUpdateEvent.GbaSlotTypeUpdated(RomGbaSlotConfigUiModel.Type.entries[it])) + } ) val gbaRomSelectorLauncher = rememberLauncherForActivityResult(FilePickerContract(Permission.READ)) { result -> @@ -118,28 +125,33 @@ private fun Content( onConfigUpdate(RomConfigUpdateEvent.GbaRomPathUpdate(result)) } } - ActionLauncherItem( - name = stringResource(id = R.string.label_rom_config_gba_rom_path), - value = romConfig.gbaCartPath ?: stringResource(id = R.string.not_set), - enabled = romConfig.loadGbaCart, - onLaunchAction = { - gbaRomSelectorLauncher.launch(Pair(romConfig.gbaCartUri, null)) - } - ) - val gbaSaveSelectorLauncher = rememberLauncherForActivityResult(FilePickerContract(Permission.READ_WRITE)) { result -> if (result != null) { onConfigUpdate(RomConfigUpdateEvent.GbaSavePathUpdate(result)) } } - ActionLauncherItem( - name = stringResource(id = R.string.label_rom_config_gba_save_path), - value = romConfig.gbaSavePath ?: stringResource(id = R.string.not_set), - enabled = romConfig.loadGbaCart, - onLaunchAction = { - gbaSaveSelectorLauncher.launch(Pair(romConfig.gbaSaveUri, null)) + + AnimatedVisibility(visible = romConfig.gbaSlotConfig.type == RomGbaSlotConfigUiModel.Type.GbaRom) { + Column { + ActionLauncherItem( + name = stringResource(id = R.string.label_rom_config_gba_rom_path), + value = romConfig.gbaSlotConfig.gbaRomPath ?: stringResource(id = R.string.not_set), + enabled = true, + onLaunchAction = { + gbaRomSelectorLauncher.launch(Pair(null, null)) + } + ) + + ActionLauncherItem( + name = stringResource(id = R.string.label_rom_config_gba_save_path), + value = romConfig.gbaSlotConfig.gbaSavePath ?: stringResource(id = R.string.not_set), + enabled = true, + onLaunchAction = { + gbaSaveSelectorLauncher.launch(Pair(null, null)) + } + ) } - ) + } } } @@ -152,6 +164,7 @@ private fun PreviewRomConfigUi() { romConfigUiState = RomConfigUiState.Ready( RomConfigUiModel( layoutName = "Default", + gbaSlotConfig = RomGbaSlotConfigUiModel(type = RomGbaSlotConfigUiModel.Type.GbaRom) ), ), onConfigUpdate = { }, diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomDetailsScreen.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomDetailsScreen.kt index 3e006297..4f96c101 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomDetailsScreen.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomDetailsScreen.kt @@ -10,8 +10,8 @@ import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.* import androidx.compose.ui.Modifier import kotlinx.coroutines.launch -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.ui.common.MelonPreviewSet import me.magnum.melonds.ui.romdetails.model.* import me.magnum.melonds.ui.theme.MelonTheme diff --git a/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomHeaderUi.kt b/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomHeaderUi.kt index 90142ba1..93007c89 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomHeaderUi.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romdetails/ui/RomHeaderUi.kt @@ -33,8 +33,8 @@ import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.pagerTabIndicatorOffset import kotlinx.coroutines.launch import me.magnum.melonds.R -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RomConfig import me.magnum.melonds.ui.common.MelonPreviewSet import me.magnum.melonds.ui.romdetails.model.RomDetailsTab import me.magnum.melonds.ui.theme.MelonTheme diff --git a/app/src/main/java/me/magnum/melonds/ui/romlist/RomConfigDialog.kt b/app/src/main/java/me/magnum/melonds/ui/romlist/RomConfigDialog.kt deleted file mode 100644 index 9b16bd36..00000000 --- a/app/src/main/java/me/magnum/melonds/ui/romlist/RomConfigDialog.kt +++ /dev/null @@ -1,222 +0,0 @@ -package me.magnum.melonds.ui.romlist - -import android.Manifest -import android.app.Activity -import android.app.Dialog -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AlertDialog -import androidx.core.os.bundleOf -import androidx.fragment.app.DialogFragment -import androidx.fragment.app.activityViewModels -import io.reactivex.disposables.Disposable -import me.magnum.melonds.R -import me.magnum.melonds.common.Permission -import me.magnum.melonds.databinding.DialogRomConfigBinding -import me.magnum.melonds.domain.model.Rom -import me.magnum.melonds.domain.model.RomConfig -import me.magnum.melonds.domain.model.RuntimeConsoleType -import me.magnum.melonds.domain.model.RuntimeMicSource -import me.magnum.melonds.extensions.setViewEnabledRecursive -import me.magnum.melonds.parcelables.RomConfigParcelable -import me.magnum.melonds.parcelables.RomParcelable -import me.magnum.melonds.ui.layouts.LayoutSelectorActivity -import me.magnum.melonds.common.contracts.FilePickerContract -import me.magnum.melonds.extensions.isMicrophonePermissionGranted -import me.magnum.melonds.extensions.parcelable -import me.magnum.melonds.utils.FileUtils -import java.util.* - -class RomConfigDialog : DialogFragment() { - companion object { - private const val KEY_TITLE = "title" - private const val KEY_ROM = "rom" - private const val KEY_ROM_CONFIG = "rom_config" - - fun newInstance(title: String, rom: Rom): RomConfigDialog { - return RomConfigDialog().apply { - arguments = bundleOf( - KEY_TITLE to title, - KEY_ROM to RomParcelable(rom) - ) - } - } - } - - private val romListViewModel: RomListViewModel by activityViewModels() - private lateinit var binding: DialogRomConfigBinding - private var layoutNameDisposable: Disposable? = null - - private lateinit var rom: Rom - private lateinit var romConfig: RomConfig - - private val layoutPickerLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> - if (result.resultCode == Activity.RESULT_OK) { - val layoutId = result.data?.getStringExtra(LayoutSelectorActivity.KEY_SELECTED_LAYOUT_ID)?.let { UUID.fromString(it) } - onLayoutIdSelected(layoutId) - } - } - private val gbaRomFilePicker = registerForActivityResult(FilePickerContract(Permission.READ)) { - if (it != null) { - onGbaRomPathSelected(it) - } - } - private val gbaSramFilePicker = registerForActivityResult(FilePickerContract(Permission.READ_WRITE)) { - if (it != null) { - onGbaSavePathSelected(it) - } - } - private val microphonePermissionLauncher = - registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted -> - if (granted) { - onRuntimeMicSourceSelected(RuntimeMicSource.DEVICE) - } - } - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - // ROM is immutable so we can use the arguments' one. Only the ROM config needs to be saved if the fragment is rebuilt - rom = arguments?.parcelable(KEY_ROM)?.rom ?: return - romConfig = if (savedInstanceState != null) { - savedInstanceState.parcelable(KEY_ROM_CONFIG)?.romConfig ?: return - } else { - rom.config.copy() - } - } - - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - binding = DialogRomConfigBinding.inflate(layoutInflater) - - return AlertDialog.Builder(requireContext()) - .setView(binding.root) - .setCancelable(true) - .create() - } - - override fun onStart() { - super.onStart() - isCancelable = true - - val title = arguments?.getString(KEY_TITLE) - - binding.layoutPrefSystem.setOnClickListener { - AlertDialog.Builder(requireContext()) - .setTitle(R.string.label_rom_config_console) - .setSingleChoiceItems(R.array.game_runtime_console_type_options, romConfig.runtimeConsoleType.ordinal) { dialog, which -> - val newConsoleType = RuntimeConsoleType.entries[which] - onRuntimeConsoleTypeSelected(newConsoleType) - dialog.dismiss() - } - .setNegativeButton(R.string.cancel) { dialog, _ -> - dialog.cancel() - } - .show() - } - binding.layoutPrefRuntimeMicSource.setOnClickListener { - AlertDialog.Builder(requireContext()) - .setTitle(R.string.microphone_source) - .setSingleChoiceItems(R.array.game_runtime_mic_source_options, romConfig.runtimeMicSource.ordinal) { dialog, which -> - val newMicSource = RuntimeMicSource.entries[which] - // Request mic permission if required - if (newMicSource == RuntimeMicSource.DEVICE && !requireContext().isMicrophonePermissionGranted()) { - microphonePermissionLauncher.launch(Manifest.permission.RECORD_AUDIO) - } else { - onRuntimeMicSourceSelected(newMicSource) - } - - dialog.dismiss() - } - .setNegativeButton(R.string.cancel) { dialog, _ -> - dialog.cancel() - } - .show() - } - binding.layoutPrefLayout.setOnClickListener { - val intent = Intent(requireContext(), LayoutSelectorActivity::class.java).apply { - putExtra(LayoutSelectorActivity.KEY_SELECTED_LAYOUT_ID, romConfig.layoutId?.toString()) - } - layoutPickerLauncher.launch(intent) - } - binding.layoutPrefLoadGbaRom.setOnClickListener { binding.switchLoadGbaRom.toggle() } - binding.layoutPrefGbaRomPath.setOnClickListener { - gbaRomFilePicker.launch(Pair(romConfig.gbaCartPath, null)) - } - layoutNameDisposable = romListViewModel.getLayout(romConfig.layoutId).subscribe { layout -> - binding.textPrefLayout.text = layout.name - } - binding.layoutPrefGbaSavePath.setOnClickListener { - gbaSramFilePicker.launch(Pair(romConfig.gbaSavePath, null)) - } - binding.switchLoadGbaRom.setOnCheckedChangeListener { _, isChecked -> setLoadGbaRom(isChecked) } - binding.textRomConfigTitle.text = title - - onRuntimeConsoleTypeSelected(romConfig.runtimeConsoleType) - onRuntimeMicSourceSelected(romConfig.runtimeMicSource) - - binding.switchLoadGbaRom.isChecked = romConfig.loadGbaCart - binding.textPrefGbaRomPath.text = getUriPathOrDefault(romConfig.gbaCartPath) - binding.textPrefGbaSavePath.text = getUriPathOrDefault(romConfig.gbaSavePath) - - binding.layoutPrefGbaRomPath.setViewEnabledRecursive(romConfig.loadGbaCart) - binding.layoutPrefGbaSavePath.setViewEnabledRecursive(romConfig.loadGbaCart) - - binding.buttonRomConfigOk.setOnClickListener { - romListViewModel.updateRomConfig(rom, romConfig) - dismiss() - } - binding.buttonRomConfigCancel.setOnClickListener { dismiss() } - } - - override fun onSaveInstanceState(outState: Bundle) { - super.onSaveInstanceState(outState) - outState.putParcelable(KEY_ROM_CONFIG, RomConfigParcelable(romConfig)) - } - - private fun setLoadGbaRom(loadGbaRom: Boolean) { - romConfig.loadGbaCart = loadGbaRom - binding.layoutPrefGbaRomPath.setViewEnabledRecursive(loadGbaRom) - binding.layoutPrefGbaSavePath.setViewEnabledRecursive(loadGbaRom) - } - - private fun onRuntimeConsoleTypeSelected(consoleType: RuntimeConsoleType) { - val options = resources.getStringArray(R.array.game_runtime_console_type_options) - romConfig.runtimeConsoleType = consoleType - binding.textPrefRuntimeConsoleType.text = options[consoleType.ordinal] - } - - private fun onRuntimeMicSourceSelected(micSource: RuntimeMicSource) { - val options = resources.getStringArray(R.array.game_runtime_mic_source_options) - romConfig.runtimeMicSource = micSource - binding.textPrefRuntimeMicSource.text = options[micSource.ordinal] - } - - private fun onLayoutIdSelected(layoutId: UUID?) { - romConfig.layoutId = layoutId - layoutNameDisposable?.dispose() - layoutNameDisposable = romListViewModel.getLayout(layoutId).subscribe { layout -> - binding.textPrefLayout.text = layout.name - } - } - - private fun onGbaRomPathSelected(romFileUri: Uri) { - romConfig.gbaCartPath = romFileUri - binding.textPrefGbaRomPath.text = getUriPathOrDefault(romFileUri) - } - - private fun onGbaSavePathSelected(saveFileUri: Uri) { - romConfig.gbaSavePath = saveFileUri - binding.textPrefGbaSavePath.text = getUriPathOrDefault(saveFileUri) - } - - private fun getUriPathOrDefault(uri: Uri?): String { - return FileUtils.getAbsolutePathFromSAFUri(requireContext(), uri) ?: getString(R.string.not_set) - } - - override fun onStop() { - super.onStop() - layoutNameDisposable?.dispose() - } -} \ No newline at end of file diff --git a/app/src/main/java/me/magnum/melonds/ui/romlist/RomListActivity.kt b/app/src/main/java/me/magnum/melonds/ui/romlist/RomListActivity.kt index f7516b52..4d6e7bf2 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romlist/RomListActivity.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romlist/RomListActivity.kt @@ -29,7 +29,7 @@ import me.magnum.melonds.databinding.ActivityRomListBinding import me.magnum.melonds.domain.model.ConfigurationDirResult import me.magnum.melonds.domain.model.ConsoleType import me.magnum.melonds.domain.model.DownloadProgress -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.SortingMode import me.magnum.melonds.domain.model.Version import me.magnum.melonds.domain.model.appupdate.AppUpdate diff --git a/app/src/main/java/me/magnum/melonds/ui/romlist/RomListFragment.kt b/app/src/main/java/me/magnum/melonds/ui/romlist/RomListFragment.kt index c4e83871..00f3a684 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romlist/RomListFragment.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romlist/RomListFragment.kt @@ -34,7 +34,7 @@ import me.magnum.melonds.R import me.magnum.melonds.databinding.ItemRomConfigurableBinding import me.magnum.melonds.databinding.ItemRomSimpleBinding import me.magnum.melonds.databinding.RomListFragmentBinding -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.RomIconFiltering import me.magnum.melonds.domain.model.RomScanningStatus import me.magnum.melonds.extensions.setViewEnabledRecursive diff --git a/app/src/main/java/me/magnum/melonds/ui/romlist/RomListViewModel.kt b/app/src/main/java/me/magnum/melonds/ui/romlist/RomListViewModel.kt index 5dfc624e..8fcc3da0 100644 --- a/app/src/main/java/me/magnum/melonds/ui/romlist/RomListViewModel.kt +++ b/app/src/main/java/me/magnum/melonds/ui/romlist/RomListViewModel.kt @@ -7,14 +7,24 @@ import dagger.hilt.android.lifecycle.HiltViewModel import io.reactivex.Single import io.reactivex.disposables.CompositeDisposable import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.isActive import kotlinx.coroutines.withContext import me.magnum.melonds.common.DirectoryAccessValidator import me.magnum.melonds.common.Permission import me.magnum.melonds.common.UriPermissionManager import me.magnum.melonds.common.uridelegates.UriHandler -import me.magnum.melonds.domain.model.* +import me.magnum.melonds.domain.model.ConfigurationDirResult +import me.magnum.melonds.domain.model.ConsoleType +import me.magnum.melonds.domain.model.LayoutConfiguration +import me.magnum.melonds.domain.model.SortingMode +import me.magnum.melonds.domain.model.SortingOrder +import me.magnum.melonds.domain.model.rom.Rom +import me.magnum.melonds.domain.model.rom.config.RuntimeConsoleType import me.magnum.melonds.domain.repositories.LayoutsRepository import me.magnum.melonds.domain.repositories.RomsRepository import me.magnum.melonds.domain.repositories.SettingsRepository @@ -24,7 +34,8 @@ import me.magnum.melonds.impl.RomIconProvider import me.magnum.melonds.utils.EventSharedFlow import me.magnum.melonds.utils.SubjectSharedFlow import java.text.Normalizer -import java.util.* +import java.util.Calendar +import java.util.UUID import javax.inject.Inject @HiltViewModel @@ -101,12 +112,6 @@ class RomListViewModel @Inject constructor( romsRepository.rescanRoms() } - fun updateRomConfig(rom: Rom, newConfig: RomConfig) { - newConfig.gbaCartPath?.let { uriPermissionManager.persistFilePermissions(it, Permission.READ) } - newConfig.gbaSavePath?.let { uriPermissionManager.persistFilePermissions(it, Permission.READ_WRITE) } - romsRepository.updateRomConfig(rom, newConfig) - } - fun getLayout(layoutId: UUID?): Single { return if (layoutId == null) { Single.just(layoutsRepository.getGlobalLayoutPlaceholder()) diff --git a/app/src/main/java/me/magnum/melonds/ui/shortcutsetup/ShortcutSetupActivity.kt b/app/src/main/java/me/magnum/melonds/ui/shortcutsetup/ShortcutSetupActivity.kt index 55061e30..49bed641 100644 --- a/app/src/main/java/me/magnum/melonds/ui/shortcutsetup/ShortcutSetupActivity.kt +++ b/app/src/main/java/me/magnum/melonds/ui/shortcutsetup/ShortcutSetupActivity.kt @@ -16,7 +16,7 @@ import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import me.magnum.melonds.R -import me.magnum.melonds.domain.model.Rom +import me.magnum.melonds.domain.model.rom.Rom import me.magnum.melonds.domain.model.RomIconFiltering import me.magnum.melonds.ui.emulator.EmulatorActivity import me.magnum.melonds.ui.romlist.RomIcon diff --git a/app/src/main/res/layout/dialog_rom_config.xml b/app/src/main/res/layout/dialog_rom_config.xml deleted file mode 100644 index 87fb5699..00000000 --- a/app/src/main/res/layout/dialog_rom_config.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -