Merge pull request #11460 from t895/reveal-settings

Android: Reveal several hidden settings
This commit is contained in:
Pierre Bourdon 2023-01-29 07:00:38 +01:00 committed by GitHub
commit 05b77925cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 405 additions and 4 deletions

View File

@ -10,6 +10,7 @@ public enum BooleanSetting implements AbstractBooleanSetting
{
// These entries have the same names and order as in C++, just for consistency.
MAIN_SKIP_IPL(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SkipIPL", true),
MAIN_DSP_HLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "DSPHLE", true),
MAIN_FASTMEM(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Fastmem", true),
MAIN_CPU_THREAD(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CPUThread", true),
@ -36,8 +37,15 @@ public enum BooleanSetting implements AbstractBooleanSetting
MAIN_WIIMOTE_ENABLE_SPEAKER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE,
"WiimoteEnableSpeaker", false),
MAIN_MMU(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MMU", false),
MAIN_PAUSE_ON_PANIC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "PauseOnPanic", false),
MAIN_ACCURATE_CPU_CACHE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "AccurateCPUCache",
false),
MAIN_SYNC_GPU(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SyncGPU", false),
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),
@ -260,6 +268,10 @@ public enum BooleanSetting implements AbstractBooleanSetting
MAIN_ENABLE_CHEATS,
MAIN_OVERRIDE_REGION_SETTINGS,
MAIN_MMU,
MAIN_PAUSE_ON_PANIC,
MAIN_ACCURATE_CPU_CACHE,
MAIN_RAM_OVERRIDE_ENABLE,
MAIN_CUSTOM_RTC_ENABLE,
MAIN_DSP_JIT,
};

View File

@ -18,6 +18,8 @@ public enum IntSetting implements AbstractIntSetting
MAIN_CPU_CORE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "CPUCore",
NativeLibrary.DefaultCPUCore()),
MAIN_GC_LANGUAGE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SelectedLanguage", 0),
MAIN_MEM1_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM1Size", 0x01800000),
MAIN_MEM2_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM2Size", 0x04000000),
MAIN_SLOT_A(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotA", 8),
MAIN_SLOT_B(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotB", 255),
MAIN_SERIAL_PORT_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SerialPort1", 255),
@ -54,11 +56,16 @@ public enum IntSetting implements AbstractIntSetting
GFX_ASPECT_RATIO(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "AspectRatio", 0),
GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
"SafeTextureCacheColorSamples", 128),
GFX_PNG_COMPRESSION_LEVEL(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "PNGCompressionLevel",
6),
GFX_MSAA(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "MSAA", 1),
GFX_EFB_SCALE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "InternalResolution", 1),
GFX_SHADER_COMPILATION_MODE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS,
"ShaderCompilationMode", 0),
GFX_ENHANCE_FORCE_TEXTURE_FILTERING(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
"ForceTextureFiltering", 0),
GFX_ENHANCE_MAX_ANISOTROPY(Settings.FILE_GFX, Settings.SECTION_GFX_ENHANCEMENTS, "MaxAnisotropy",
0),
@ -80,6 +87,8 @@ public enum IntSetting implements AbstractIntSetting
private static final IntSetting[] NOT_RUNTIME_EDITABLE_ARRAY = new IntSetting[]{
MAIN_CPU_CORE,
MAIN_GC_LANGUAGE,
MAIN_MEM1_SIZE,
MAIN_MEM2_SIZE,
MAIN_SLOT_A, // Can actually be changed, but specific code is required
MAIN_SLOT_B, // Can actually be changed, but specific code is required
MAIN_SERIAL_PORT_1,

View File

@ -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,
};

View File

@ -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)
}
}

View File

@ -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;

View File

@ -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<SettingViewHolder>
implements DialogInterface.OnClickListener, Slider.OnChangeListener
@ -135,6 +144,9 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
case SettingsItem.TYPE_HYPERLINK_HEADER:
return new HeaderHyperLinkViewHolder(ListItemHeaderBinding.inflate(inflater), this);
case SettingsItem.TYPE_DATETIME_CHOICE:
return new DateTimeSettingViewHolder(ListItemSettingBinding.inflate(inflater), this);
default:
throw new IllegalArgumentException("Invalid view type: " + viewType);
}
@ -377,6 +389,63 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
mView.getActivity().startActivityForResult(intent, filePicker.getRequestType());
}
public void onDateTimeClick(DateTimeChoiceSetting item, int position)
{
mClickedItem = item;
mClickedPosition = position;
long storedTime = Long.decode(item.getSelectedValue(mView.getSettings())) * 1000;
// Helper to extract hour and minute from epoch time
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(storedTime);
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
// Start and end epoch times available for the Wii's date picker
CalendarConstraints calendarConstraints = new CalendarConstraints.Builder()
.setStart(946684800000L)
.setEnd(2082672000000L)
.build();
int timeFormat = TimeFormat.CLOCK_12H;
if (DateFormat.is24HourFormat(mView.getActivity()))
{
timeFormat = TimeFormat.CLOCK_24H;
}
MaterialDatePicker<Long> 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;

View File

@ -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;
@ -564,8 +565,13 @@ public final class SettingsFragmentPresenter
private void addGameCubeSettings(ArrayList<SettingsItem> sl)
{
sl.add(new HeaderSetting(mContext, R.string.ipl_settings, 0));
sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_SKIP_IPL, R.string.skip_main_menu,
R.string.skip_main_menu_description));
sl.add(new SingleChoiceSetting(mContext, IntSetting.MAIN_GC_LANGUAGE, R.string.system_language,
0, R.array.gameCubeSystemLanguageEntries, R.array.gameCubeSystemLanguageValues));
sl.add(new HeaderSetting(mContext, R.string.device_settings, 0));
sl.add(new SingleChoiceSetting(mContext, IntSetting.MAIN_SLOT_A, R.string.slot_a_device, 0,
R.array.slotDeviceEntries, R.array.slotDeviceValues));
sl.add(new SingleChoiceSetting(mContext, IntSetting.MAIN_SLOT_B, R.string.slot_b_device, 0,
@ -715,17 +721,103 @@ public final class SettingsFragmentPresenter
emuCoresEntries = R.array.emuCoresEntriesGeneric;
emuCoresValues = R.array.emuCoresValuesGeneric;
}
sl.add(new HeaderSetting(mContext, R.string.cpu_options, 0));
sl.add(new SingleChoiceSetting(mContext, IntSetting.MAIN_CPU_CORE, R.string.cpu_core, 0,
emuCoresEntries, emuCoresValues));
sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_MMU, R.string.mmu_enable,
R.string.mmu_enable_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_PAUSE_ON_PANIC, R.string.pause_on_panic,
R.string.pause_on_panic_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_ACCURATE_CPU_CACHE,
R.string.enable_cpu_cache, R.string.enable_cpu_cache_description));
sl.add(new HeaderSetting(mContext, R.string.clock_override, 0));
sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_OVERCLOCK_ENABLE,
R.string.overclock_enable, R.string.overclock_enable_description));
sl.add(new PercentSliderSetting(mContext, FloatSetting.MAIN_OVERCLOCK, R.string.overclock_title,
R.string.overclock_title_description, 0, 400, "%"));
AbstractIntSetting mem1Setting = new AbstractIntSetting()
{
@Override
public int getInt(Settings settings)
{
return IntSetting.MAIN_MEM1_SIZE.getInt(settings) / 1024 / 1024;
}
@Override
public void setInt(Settings settings, int newValue)
{
IntSetting.MAIN_MEM1_SIZE.setInt(settings, newValue * 1024 * 1024);
}
@Override
public boolean isOverridden(Settings settings)
{
return IntSetting.MAIN_MEM1_SIZE.isOverridden(settings);
}
@Override
public boolean isRuntimeEditable()
{
return IntSetting.MAIN_MEM1_SIZE.isRuntimeEditable();
}
@Override
public boolean delete(Settings settings)
{
return IntSetting.MAIN_MEM1_SIZE.delete(settings);
}
};
AbstractIntSetting mem2Setting = new AbstractIntSetting()
{
@Override
public int getInt(Settings settings)
{
return IntSetting.MAIN_MEM2_SIZE.getInt(settings) / 1024 / 1024;
}
@Override
public void setInt(Settings settings, int newValue)
{
IntSetting.MAIN_MEM2_SIZE.setInt(settings, newValue * 1024 * 1024);
}
@Override
public boolean isOverridden(Settings settings)
{
return IntSetting.MAIN_MEM2_SIZE.isOverridden(settings);
}
@Override
public boolean isRuntimeEditable()
{
return IntSetting.MAIN_MEM2_SIZE.isRuntimeEditable();
}
@Override
public boolean delete(Settings settings)
{
return IntSetting.MAIN_MEM2_SIZE.delete(settings);
}
};
sl.add(new HeaderSetting(mContext, R.string.memory_override, 0));
sl.add(new SwitchSetting(mContext, BooleanSetting.MAIN_RAM_OVERRIDE_ENABLE,
R.string.enable_memory_size_override,
R.string.enable_memory_size_override_description));
sl.add(new IntSliderSetting(mContext, mem1Setting, R.string.main_mem1_size, 0, 24, 64, "MB"));
sl.add(new IntSliderSetting(mContext, mem2Setting, R.string.main_mem2_size, 0, 64, 128, "MB"));
sl.add(new HeaderSetting(mContext, R.string.gpu_options, 0));
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<SettingsItem> sl, int serialPort1Type)
@ -800,6 +892,37 @@ public final class SettingsFragmentPresenter
sl.add(new SingleChoiceSetting(mContext, IntSetting.GFX_ENHANCE_MAX_ANISOTROPY,
R.string.anisotropic_filtering, R.string.anisotropic_filtering_description,
R.array.anisotropicFilteringEntries, R.array.anisotropicFilteringValues));
AbstractIntSetting filteringSetting = new AbstractIntSetting()
{
@Override public int getInt(Settings settings)
{
return IntSetting.GFX_ENHANCE_FORCE_TEXTURE_FILTERING.getInt(settings);
}
@Override public void setInt(Settings settings, int newValue)
{
BooleanSetting.GFX_ENHANCE_FORCE_FILTERING.setBoolean(settings, (newValue > 0));
IntSetting.GFX_ENHANCE_FORCE_TEXTURE_FILTERING.setInt(settings, newValue);
}
@Override public boolean isOverridden(Settings settings)
{
return IntSetting.GFX_ENHANCE_FORCE_TEXTURE_FILTERING.isOverridden(settings);
}
@Override public boolean isRuntimeEditable()
{
return IntSetting.GFX_ENHANCE_FORCE_TEXTURE_FILTERING.isRuntimeEditable();
}
@Override public boolean delete(Settings settings)
{
return IntSetting.GFX_ENHANCE_FORCE_TEXTURE_FILTERING.delete(settings);
}
};
sl.add(new SingleChoiceSetting(mContext, filteringSetting, R.string.texture_filtering,
R.string.texture_filtering_description, R.array.textureFilteringEntries,
R.array.textureFilteringValues));
int stereoModeValue = IntSetting.GFX_STEREO_MODE.getInt(mSettings);
final int anaglyphMode = 3;
@ -821,8 +944,6 @@ public final class SettingsFragmentPresenter
R.string.scaled_efb_copy, R.string.scaled_efb_copy_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_ENABLE_PIXEL_LIGHTING,
R.string.per_pixel_lighting, R.string.per_pixel_lighting_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_ENHANCE_FORCE_FILTERING,
R.string.force_texture_filtering, R.string.force_texture_filtering_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_ENHANCE_FORCE_TRUE_COLOR,
R.string.force_24bit_color, R.string.force_24bit_color_description));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_DISABLE_FOG, R.string.disable_fog,
@ -944,8 +1065,12 @@ public final class SettingsFragmentPresenter
R.string.defer_efb_invalidation, R.string.defer_efb_invalidation_description));
sl.add(new InvertedSwitchSetting(mContext, BooleanSetting.GFX_HACK_FAST_TEXTURE_SAMPLING,
R.string.manual_texture_sampling, R.string.manual_texture_sampling_description));
sl.add(new HeaderSetting(mContext, R.string.frame_dumping, 0));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_INTERNAL_RESOLUTION_FRAME_DUMPS,
R.string.internal_resolution_dumps, R.string.internal_resolution_dumps_description));
sl.add(new IntSliderSetting(mContext, IntSetting.GFX_PNG_COMPRESSION_LEVEL,
R.string.png_compression_level, 0, 0, 9, ""));
sl.add(new HeaderSetting(mContext, R.string.debugging, 0));
sl.add(new SwitchSetting(mContext, BooleanSetting.GFX_ENABLE_WIREFRAME,

View File

@ -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
}
}

View File

@ -54,6 +54,12 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder
Toast.LENGTH_SHORT).show();
}
protected static void showIplNotAvailableError()
{
Toast.makeText(DolphinApplication.getAppContext(), R.string.ipl_not_found, Toast.LENGTH_SHORT)
.show();
}
/**
* Called by the adapter to set this ViewHolder's child views to display the list item
* it must now represent.

View File

@ -7,13 +7,20 @@ import android.view.View;
import androidx.annotation.Nullable;
import org.dolphinemu.dolphinemu.databinding.ListItemSettingSwitchBinding;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.SwitchSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
public final class SwitchSettingViewHolder extends SettingViewHolder
{
private SwitchSetting mItem;
private boolean iplExists = false;
private final ListItemSettingSwitchBinding mBinding;
@ -32,11 +39,43 @@ public final class SwitchSettingViewHolder extends SettingViewHolder
mBinding.textSettingDescription.setText(item.getDescription());
mBinding.settingSwitch.setChecked(mItem.isChecked(getAdapter().getSettings()));
mBinding.settingSwitch.setEnabled(true);
mBinding.settingSwitch.setEnabled(mItem.isEditable());
// Check for IPL to make sure user can skip.
if (mItem.getSetting() == BooleanSetting.MAIN_SKIP_IPL)
{
ArrayList<String> iplDirs = new ArrayList<>(Arrays.asList("USA", "JAP", "EUR"));
for (String dir : iplDirs)
{
File iplFile = new File(DirectoryInitialization.getUserDirectory(),
File.separator + "GC" + File.separator + dir + File.separator + "IPL.bin");
if (iplFile.exists())
{
iplExists = true;
break;
}
}
if (mItem.isChecked(getAdapter().getSettings()))
{
mBinding.settingSwitch.setEnabled(iplExists);
}
else
{
mBinding.settingSwitch.setEnabled(true);
}
}
mBinding.settingSwitch.setOnCheckedChangeListener((buttonView, isChecked) ->
{
// If a user has skip IPL disabled previously and deleted their IPL file, we need to allow
// them to skip it or else their game will appear broken. However, once this is enabled, we
// need to disable the option again to prevent the same issue from occurring.
if (mItem.getSetting() == BooleanSetting.MAIN_SKIP_IPL && !iplExists && isChecked)
{
mBinding.settingSwitch.setEnabled(false);
}
getAdapter().onBooleanClick(mItem, mBinding.settingSwitch.isChecked());
setStyle(mBinding.textSettingName, mItem);
@ -54,6 +93,15 @@ public final class SwitchSettingViewHolder extends SettingViewHolder
return;
}
if (mItem.getSetting() == BooleanSetting.MAIN_SKIP_IPL && !iplExists)
{
if (mItem.isChecked(getAdapter().getSettings()))
{
showIplNotAvailableError();
return;
}
}
mBinding.settingSwitch.toggle();
}

View File

@ -293,7 +293,7 @@
<!-- Anisotropic Filtering Preference -->
<string-array name="anisotropicFilteringEntries">
<item>@string/multiple_one</item>
<item>@string/filtering_default</item>
<item>@string/multiple_two</item>
<item>@string/multiple_four</item>
<item>@string/multiple_eight</item>
@ -307,6 +307,18 @@
<item>4</item>
</integer-array>
<!-- Texture Filtering Preference -->
<string-array name="textureFilteringEntries">
<item>@string/filtering_default</item>
<item>@string/filtering_nearest</item>
<item>@string/filtering_linear</item>
</string-array>
<integer-array name="textureFilteringValues">
<item>0</item>
<item>1</item>
<item>2</item>
</integer-array>
<!-- Stereoscopy Preference -->
<string-array name="stereoscopyEntries">
<item>@string/stereoscopy_off</item>

View File

@ -128,6 +128,10 @@
<string name="speed_limit">Speed Limit (0% = Unlimited)</string>
<string name="overclock_warning">WARNING: Changing this from the default (100%) WILL break games and cause glitches. Please do not report bugs that occur with a non-default clock.</string>
<string name="gamecube_submenu">GameCube</string>
<string name="ipl_settings">IPL Settings</string>
<string name="skip_main_menu">Skip Main Menu</string>
<string name="skip_main_menu_description">Put IPL ROMs in User/GC/&lt;region&gt;</string>
<string name="device_settings">Device Settings</string>
<string name="system_language">System Language</string>
<string name="slot_a_device">GameCube Slot A Device</string>
<string name="slot_b_device">GameCube Slot B Device</string>
@ -250,6 +254,8 @@
<string name="FSAA_description">Reduces the amount of aliasing caused by rasterizing 3D graphics. This makes the rendered picture look less blocky. Heavily decreases emulation speed and sometimes causes issues.</string>
<string name="anisotropic_filtering">Anisotropic Filtering</string>
<string name="anisotropic_filtering_description">Enhances visual quality of textures that are at oblique viewing angles. Might cause issues in a small number of games.</string>
<string name="texture_filtering">Texture Filtering</string>
<string name="texture_filtering_description">Overrides the texture scaling filter selected by the game. Any option except \'Default\' will alter the look of the game\'s textures and might cause issues in a small number of games.</string>
<string name="post_processing_shader">Post-Processing Effect</string>
<string name="post_processing_shader_description">Apply a post-processing effect after finishing a frame</string>
<string name="postprocessing_shader">Post Processing Shader</string>
@ -368,7 +374,9 @@
<string name="manual_texture_sampling">Manual Texture Sampling</string>
<string name="manual_texture_sampling_description">Use a manual implementation of texture sampling instead of the graphics backend\'s built-in functionality.</string>
<string name="internal_resolution_dumps">Dump Frames at Internal Resolution</string>
<string name="frame_dumping">Frame Dumping</string>
<string name="internal_resolution_dumps_description">Creates frame dumps and screenshots at the internal resolution of the renderer, rather than the size of the window it is displayed within. If the aspect ratio is widescreen, the output image will be scaled horizontally to preserve the vertical resolution.</string>
<string name="png_compression_level">PNG Compression Level</string>
<string name="debugging">Debugging</string>
<string name="wireframe">Enable Wireframe</string>
<string name="show_stats">Show Statistics</string>
@ -381,15 +389,33 @@
<!-- Advanced Settings -->
<string name="advanced_submenu">Advanced</string>
<string name="cpu_options">CPU Options</string>
<string name="cpu_core">CPU Core</string>
<string name="mmu_enable">Enable MMU</string>
<string name="mmu_enable_description">Enables the Memory Management Unit. Needed for some games, but may reduce performance.</string>
<string name="pause_on_panic">Pause on Panic</string>
<string name="pause_on_panic_description">Pauses the emulation if a Read/Write or Unknown Instruction panic occurs. The performance impact is the same as having Enable MMU on.</string>
<string name="enable_cpu_cache">Enable Write-Back Cache (slow)</string>
<string name="enable_cpu_cache_description">Enables emulation of the CPU write-back cache. Enabling will have a significant impact on performance. This should be left disabled unless absolutely needed.</string>
<string name="clock_override">Clock Override</string>
<string name="overclock_enable">Override Emulated CPU Clock Speed</string>
<string name="overclock_enable_description">Higher values can make variable-framerate games run at a higher framerate, requiring a powerful device. Lower values make games run at a lower framerate, increasing emulation speed, but reducing the emulated console\'s performance.</string>
<string name="overclock_title">Emulated CPU Clock Speed</string>
<string name="overclock_title_description">Adjusts the emulated CPU\'s clock rate if \"Override Emulated CPU Clock Speed\" is enabled.</string>
<string name="memory_override">Memory Override</string>
<string name="enable_memory_size_override">Enable Emulated Memory Size Override</string>
<string name="enable_memory_size_override_description">Adjusts the amount of RAM in the emulated console.\n\nWARNING: Enabling this will completely break many games. Only a small number of games can benefit from this.</string>
<string name="main_mem1_size">MEM1 Size</string>
<string name="main_mem2_size">MEM2 Size</string>
<string name="gpu_options">GPU Options</string>
<string name="synchronize_gpu_thread">Synchronize GPU Thread</string>
<string name="synchronize_gpu_thread_description">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!</string>
<string name="custom_rtc_options">Custom RTC Options</string>
<string name="custom_rtc_enable">Enable Custom RTC</string>
<string name="custom_rtc_description">This settings allows you to set a custom real time clock (RTC) separate from your current system time.</string>
<string name="set_custom_rtc">Set Custom RTC</string>
<string name="select_rtc_date">Select RTC Date</string>
<string name="select_rtc_time">Select RTC Time</string>
<!-- Log Configuration -->
<string name="log_submenu">Log</string>
@ -623,6 +649,7 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="path_not_changeable_scoped_storage">Due to the Scoped Storage policy in Android 11 and newer, you can\'t change this path.</string>
<string name="load_settings">Loading Settings…</string>
<string name="setting_not_runtime_editable">This setting can\'t be changed while a game is running.</string>
<string name="ipl_not_found">IPL not found</string>
<string name="setting_clear_info">Long press a setting to clear it.</string>
<string name="setting_clear_confirm">Do you want to restore this setting to its default value?</string>
<string name="setting_cleared">Setting cleared</string>
@ -752,6 +779,11 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="multiple_eight">8x</string>
<string name="multiple_sixteen">16x</string>
<!-- Texture Filtering Preference -->
<string name="filtering_default">Default</string>
<string name="filtering_nearest">Force Nearest</string>
<string name="filtering_linear">Force Linear</string>
<!-- Stereoscopy Preference -->
<string name="stereoscopy_off">Off</string>
<string name="stereoscopy_side_by_side">Side-by-Side</string>