From 3eee52cb6bbebfc6b44b43aa85cd22b17b27aca5 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 12 Apr 2025 13:39:34 +0200 Subject: Android: Create toggle for enabling/disabling time tracking --- .../dolphinemu/features/settings/model/BooleanSetting.kt | 7 +++++++ .../dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt | 8 ++++++++ 2 files changed, 15 insertions(+) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt index 16ee12e307..afe48b86d7 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.kt @@ -132,6 +132,12 @@ enum class BooleanSetting( ), MAIN_WII_WIILINK_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableWiiLink", false), MAIN_DSP_JIT(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "EnableJIT", true), + MAIN_TIME_TRACKING( + Settings.FILE_DOLPHIN, + Settings.SECTION_INI_GENERAL, + "EnablePlayTimeTracking", + true + ), MAIN_EXPAND_TO_CUTOUT_AREA( Settings.FILE_DOLPHIN, Settings.SECTION_INI_INTERFACE, @@ -916,6 +922,7 @@ enum class BooleanSetting( MAIN_RAM_OVERRIDE_ENABLE, MAIN_CUSTOM_RTC_ENABLE, MAIN_DSP_JIT, + MAIN_TIME_TRACKING, MAIN_EMULATE_SKYLANDER_PORTAL, MAIN_EMULATE_INFINITY_BASE ) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index ff82f4c63c..e0aa32e15c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -344,6 +344,14 @@ class SettingsFragmentPresenter( R.string.osd_messages_description ) ) + sl.add( + SwitchSetting( + context, + BooleanSetting.MAIN_TIME_TRACKING, + R.string.time_tracking, + R.string.time_tracking_description + ) + ) val appTheme: AbstractIntSetting = object : AbstractIntSetting { override val isOverridden: Boolean -- cgit v1.2.3 From b8e70df413ddd4663aa8e65a6f9d8a1e059c64c7 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 12 Apr 2025 14:27:09 +0200 Subject: Android: Show time played in game details Unlike in DolphinQt, there isn't much space to show playtimes directly in the game list, so I've put it in the game details dialog instead. --- .../dolphinemu/dialogs/GameDetailsDialog.kt | 31 ++++++++++++++++++++++ .../org/dolphinemu/dolphinemu/model/GameFile.kt | 11 ++++++++ 2 files changed, 42 insertions(+) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt index 53b1467bbc..0384da89c0 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.kt @@ -19,6 +19,7 @@ import kotlinx.coroutines.launch import org.dolphinemu.dolphinemu.NativeLibrary import org.dolphinemu.dolphinemu.databinding.DialogGameDetailsBinding import org.dolphinemu.dolphinemu.databinding.DialogGameDetailsTvBinding +import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting import org.dolphinemu.dolphinemu.model.GameFile class GameDetailsDialog : DialogFragment() { @@ -35,6 +36,21 @@ class GameDetailsDialog : DialogFragment() { if (requireActivity() is AppCompatActivity) { binding = DialogGameDetailsBinding.inflate(layoutInflater) binding.apply { + if (BooleanSetting.MAIN_TIME_TRACKING.boolean) { + lifecycleScope.launch { + val totalMs = gameFile.getTimePlayedMs() + val totalMinutes = totalMs / 60000 + val totalHours = totalMinutes / 60 + textTimePlayed.text = resources.getString( + R.string.game_details_time_played, + totalHours, + totalMinutes % 60 + ) + } + } else { + textTimePlayed.visibility = View.GONE + } + textGameTitle.text = gameFile.getTitle() textDescription.text = gameFile.getDescription() if (gameFile.getDescription().isEmpty()) { @@ -87,6 +103,21 @@ class GameDetailsDialog : DialogFragment() { } else { tvBinding = DialogGameDetailsTvBinding.inflate(layoutInflater) tvBinding.apply { + if (BooleanSetting.MAIN_TIME_TRACKING.boolean) { + lifecycleScope.launch { + val totalMs = gameFile.getTimePlayedMs() + val totalMinutes = totalMs / 60000 + val totalHours = totalMinutes / 60 + textTimePlayed.text = resources.getString( + R.string.game_details_time_played, + totalHours, + totalMinutes % 60 + ) + } + } else { + textTimePlayed.visibility = View.GONE + } + textGameTitle.text = gameFile.getTitle() textDescription.text = gameFile.getDescription() if (gameFile.getDescription().isEmpty()) { diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt index 347433f552..26da174285 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFile.kt @@ -3,6 +3,8 @@ package org.dolphinemu.dolphinemu.model import androidx.annotation.Keep +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext @Keep class GameFile private constructor(private val pointer: Long) { @@ -54,6 +56,15 @@ class GameFile private constructor(private val pointer: Long) { external fun getBannerHeight(): Int + suspend fun getTimePlayedMs(): Long { + // getTimePlayedMsInternal reads from disk, so let's use coroutines. + return withContext(Dispatchers.IO) { + getTimePlayedMsInternal() + } + } + + external private fun getTimePlayedMsInternal(): Long + val customCoverPath: String get() = "${getPath().substring(0, getPath().lastIndexOf("."))}.cover.png" -- cgit v1.2.3