From bbb83054afe13451d1f8b463b61b9e057d3db267 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Tue, 17 Jan 2023 13:18:33 -0500 Subject: [PATCH] Android: Expose custom rtc options --- .../settings/model/BooleanSetting.java | 3 + .../settings/model/StringSetting.java | 4 ++ .../model/view/DateTimeChoiceSetting.kt | 31 +++++++++ .../settings/model/view/SettingsItem.java | 1 + .../features/settings/ui/SettingsAdapter.java | 69 +++++++++++++++++++ .../ui/SettingsFragmentPresenter.java | 7 ++ .../viewholder/DateTimeSettingViewHolder.kt | 52 ++++++++++++++ .../app/src/main/res/values/strings.xml | 6 ++ 8 files changed, 173 insertions(+) create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/DateTimeChoiceSetting.kt create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/DateTimeSettingViewHolder.kt diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java index b473831adc..e7b22c36d9 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java @@ -44,6 +44,8 @@ public enum BooleanSetting implements AbstractBooleanSetting MAIN_OVERCLOCK_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "OverclockEnable", false), MAIN_RAM_OVERRIDE_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "RAMOverrideEnable", false), + MAIN_CUSTOM_RTC_ENABLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EnableCustomRTC", + false), MAIN_AUTO_DISC_CHANGE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AutoDiscChange", false), MAIN_ALLOW_SD_WRITES(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "WiiSDCardAllowWrites", true), @@ -267,6 +269,7 @@ public enum BooleanSetting implements AbstractBooleanSetting MAIN_PAUSE_ON_PANIC, MAIN_ACCURATE_CPU_CACHE, MAIN_RAM_OVERRIDE_ENABLE, + MAIN_CUSTOM_RTC_ENABLE, MAIN_DSP_JIT, }; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java index d838f6879b..09af07ef76 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java @@ -21,6 +21,9 @@ public enum StringSetting implements AbstractStringSetting MAIN_BBA_BUILTIN_DNS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_BUILTIN_DNS", "149.56.167.128"), + MAIN_CUSTOM_RTC_VALUE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CustomRTCValue", + "0x386d4380"), + MAIN_GFX_BACKEND(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "GFXBackend", NativeLibrary.GetDefaultGraphicsBackendName()), @@ -39,6 +42,7 @@ public enum StringSetting implements AbstractStringSetting "PostProcessingShader", ""); private static final StringSetting[] NOT_RUNTIME_EDITABLE_ARRAY = new StringSetting[]{ + MAIN_CUSTOM_RTC_VALUE, MAIN_GFX_BACKEND, }; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/DateTimeChoiceSetting.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/DateTimeChoiceSetting.kt new file mode 100644 index 0000000000..d37ea57a98 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/DateTimeChoiceSetting.kt @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.settings.model.view + +import android.content.Context +import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting +import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting +import org.dolphinemu.dolphinemu.features.settings.model.Settings + +class DateTimeChoiceSetting( + context: Context, + private val setting: AbstractStringSetting, + nameId: Int, + descriptionId: Int +) : SettingsItem(context, nameId, descriptionId) { + override fun getType(): Int { + return TYPE_DATETIME_CHOICE + } + + override fun getSetting(): AbstractSetting { + return setting + } + + fun setSelectedValue(settings: Settings?, selection: String) { + setting.setString(settings, selection) + } + + fun getSelectedValue(settings: Settings): String { + return setting.getString(settings) + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java index 21b782fcb3..7b41c8e3f8 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java @@ -29,6 +29,7 @@ public abstract class SettingsItem public static final int TYPE_RUN_RUNNABLE = 10; public static final int TYPE_STRING = 11; public static final int TYPE_HYPERLINK_HEADER = 12; + public static final int TYPE_DATETIME_CHOICE = 13; private final CharSequence mName; private final CharSequence mDescription; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java index b51d87e5a9..89db998bbd 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java @@ -9,6 +9,7 @@ import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.os.Build; import android.provider.DocumentsContract; +import android.text.format.DateFormat; import android.view.LayoutInflater; import android.view.ViewGroup; import android.widget.TextView; @@ -20,10 +21,14 @@ import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.color.MaterialColors; +import com.google.android.material.datepicker.CalendarConstraints; +import com.google.android.material.datepicker.MaterialDatePicker; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.elevation.ElevationOverlayProvider; import com.google.android.material.slider.Slider; import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.timepicker.MaterialTimePicker; +import com.google.android.material.timepicker.TimeFormat; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.databinding.DialogInputStringBinding; @@ -34,6 +39,7 @@ import org.dolphinemu.dolphinemu.databinding.ListItemSettingSwitchBinding; import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding; import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog; import org.dolphinemu.dolphinemu.features.settings.model.Settings; +import org.dolphinemu.dolphinemu.features.settings.model.view.DateTimeChoiceSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SwitchSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker; import org.dolphinemu.dolphinemu.features.settings.model.view.FloatSliderSetting; @@ -47,6 +53,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.InputStringSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting; +import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.DateTimeSettingViewHolder; import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.FilePickerViewHolder; import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.HeaderHyperLinkViewHolder; import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.HeaderViewHolder; @@ -68,6 +75,8 @@ import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.util.ArrayList; +import java.util.Calendar; +import java.util.TimeZone; public final class SettingsAdapter extends RecyclerView.Adapter implements DialogInterface.OnClickListener, Slider.OnChangeListener @@ -135,6 +144,9 @@ public final class SettingsAdapter extends RecyclerView.Adapter datePicker = MaterialDatePicker.Builder.datePicker() + .setSelection(storedTime) + .setTitleText(R.string.select_rtc_date) + .setCalendarConstraints(calendarConstraints) + .build(); + MaterialTimePicker timePicker = new MaterialTimePicker.Builder() + .setTimeFormat(timeFormat) + .setHour(calendar.get(Calendar.HOUR_OF_DAY)) + .setMinute(calendar.get(Calendar.MINUTE)) + .setTitleText(R.string.select_rtc_time) + .build(); + + datePicker.addOnPositiveButtonClickListener( + selection -> timePicker.show(mView.getActivity().getSupportFragmentManager(), + "TimePicker")); + timePicker.addOnPositiveButtonClickListener(selection -> + { + long epochTime = datePicker.getSelection() / 1000; + epochTime += (long) timePicker.getHour() * 60 * 60; + epochTime += (long) timePicker.getMinute() * 60; + String rtcString = "0x" + Long.toHexString(epochTime); + if (!item.getSelectedValue(mView.getSettings()).equals(rtcString)) + { + notifyItemChanged(mClickedPosition); + mView.onSettingChanged(); + } + + item.setSelectedValue(mView.getSettings(), rtcString); + + mClickedItem = null; + }); + datePicker.show(mView.getActivity().getSupportFragmentManager(), "DatePicker"); + } + public void onFilePickerConfirmation(String selectedFile) { FilePicker filePicker = (FilePicker) mClickedItem; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java index b5282a296d..9d51007c4f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java @@ -25,6 +25,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.PostProcessing; import org.dolphinemu.dolphinemu.features.settings.model.Settings; import org.dolphinemu.dolphinemu.features.settings.model.StringSetting; import org.dolphinemu.dolphinemu.features.settings.model.WiimoteProfileStringSetting; +import org.dolphinemu.dolphinemu.features.settings.model.view.DateTimeChoiceSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.SwitchSetting; import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker; import org.dolphinemu.dolphinemu.features.settings.model.view.HeaderSetting; @@ -811,6 +812,12 @@ public final class SettingsFragmentPresenter sl.add(new SingleChoiceSetting(mContext, synchronizeGpuThread, R.string.synchronize_gpu_thread, R.string.synchronize_gpu_thread_description, R.array.synchronizeGpuThreadEntries, R.array.synchronizeGpuThreadValues)); + + sl.add(new HeaderSetting(mContext, R.string.custom_rtc_options, 0)); + sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_CUSTOM_RTC_ENABLE, + R.string.custom_rtc_enable, R.string.custom_rtc_description)); + sl.add(new DateTimeChoiceSetting(mContext, StringSetting.MAIN_CUSTOM_RTC_VALUE, + R.string.set_custom_rtc, 0)); } private void addSerialPortSubSettings(ArrayList sl, int serialPort1Type) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/DateTimeSettingViewHolder.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/DateTimeSettingViewHolder.kt new file mode 100644 index 0000000000..79693e9c64 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/DateTimeSettingViewHolder.kt @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.settings.ui.viewholder + +import android.text.TextUtils +import android.view.View +import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding +import org.dolphinemu.dolphinemu.features.settings.model.view.DateTimeChoiceSetting +import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem +import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter +import java.time.Instant +import java.time.ZoneId +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter +import java.time.format.FormatStyle + +class DateTimeSettingViewHolder( + private val binding: ListItemSettingBinding, + adapter: SettingsAdapter +) : SettingViewHolder(binding.root, adapter) { + private var mItem: DateTimeChoiceSetting? = null + + override fun bind(item: SettingsItem) { + mItem = item as DateTimeChoiceSetting + val inputTime = mItem!!.getSelectedValue(adapter.settings) + binding.textSettingName.text = item.getName() + + if (!TextUtils.isEmpty(inputTime)) { + val epochTime = inputTime.substring(2).toLong(16) + val instant = Instant.ofEpochMilli(epochTime * 1000) + val zonedTime = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC")) + val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) + binding.textSettingDescription.text = dateFormatter.format(zonedTime) + } else { + binding.textSettingDescription.text = item.getDescription() + } + setStyle(binding.textSettingName, mItem) + } + + override fun onClick(clicked: View) { + if (!mItem!!.isEditable) { + showNotRuntimeEditableError() + return + } + adapter.onDateTimeClick(mItem, bindingAdapterPosition) + setStyle(binding.textSettingName, mItem) + } + + override fun getItem(): SettingsItem? { + return mItem + } +} diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 51502c1943..163a78c3be 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -404,6 +404,12 @@ GPU Options Synchronize GPU Thread Synchronizing the GPU thread reduces the risk of games crashing or becoming unstable with dual core enabled, but can also reduce the performance gain of dual core. If unsure, select \"On Idle Skipping\". Selecting \"Never\" is risky and not recommended! + Custom RTC Options + Enable Custom RTC + This settings allows you to set a custom real time clock (RTC) separate from your current system time. + Set Custom RTC + Select RTC Date + Select RTC Time Log