Android: Specify ini file for every setting

Load all the inis at once, choose which one to write to, and save them all
at the same time. This allows us to modify settings from different files
on the same settings page.
This commit is contained in:
Sean Maas 2016-11-07 21:49:06 -05:00
parent 017ab71fcf
commit 128c1f04ad
20 changed files with 293 additions and 323 deletions

View File

@ -4,9 +4,9 @@ public final class BooleanSetting extends Setting
{
private boolean mValue;
public BooleanSetting(String key, String section, boolean value)
public BooleanSetting(String key, String section, int file, boolean value)
{
super(key, section);
super(key, section, file);
mValue = value;
}

View File

@ -4,9 +4,9 @@ public final class FloatSetting extends Setting
{
private float mValue;
public FloatSetting(String key, String section, float value)
public FloatSetting(String key, String section, int file, float value)
{
super(key, section);
super(key, section, file);
mValue = value;
}

View File

@ -4,9 +4,9 @@ public final class IntSetting extends Setting
{
private int mValue;
public IntSetting(String key, String section, int value)
public IntSetting(String key, String section, int file, int value)
{
super(key, section);
super(key, section, file);
mValue = value;
}

View File

@ -10,17 +10,20 @@ public abstract class Setting
{
private String mKey;
private String mSection;
private int mFile;
/**
* Base constructor.
*
* @param key Everything to the left of the = in a line from the ini file.
* @param section The corresponding recent section header; e.g. [Core] or [Enhancements] without the brackets.
* @param file The ini file the Setting is stored in.
*/
public Setting(String key, String section)
public Setting(String key, String section, int file)
{
mKey = key;
mSection = section;
mFile = file;
}
/**
@ -41,6 +44,15 @@ public abstract class Setting
return mSection;
}
/**
*
* @return The ini file the Setting is stored in.
*/
public int getFile()
{
return mFile;
}
/**
* @return A representation of this Setting's backing value converted to a String (e.g. for serialization).
*/

View File

@ -4,7 +4,7 @@ import java.util.HashMap;
/**
* A semantically-related group of Settings objects. These Settings are
* internally stored as a Hashmap.
* internally stored as a HashMap.
*/
public final class SettingSection
{
@ -28,18 +28,17 @@ public final class SettingSection
}
/**
* Convenience method; inserts a value directly into the backing Hashmap.
* Convenience method; inserts a value directly into the backing HashMap.
*
* @param key The key where the Setting will be inserted.
* @param setting The Setting to be inserted.
*/
public void putSetting(String key, Setting setting)
public void putSetting(Setting setting)
{
mSettings.put(key, setting);
mSettings.put(setting.getKey(), setting);
}
/**
* Convenience method; gets a value directly from the backing Hashmap.
* Convenience method; gets a value directly from the backing HashMap.
*
* @param key Used to retrieve the Setting.
* @return A Setting object (you should probably cast this before using)

View File

@ -4,9 +4,9 @@ public final class StringSetting extends Setting
{
private String mValue;
public StringSetting(String key, String section, String value)
public StringSetting(String key, String section, int file, String value)
{
super(key, section);
super(key, section, file);
mValue = value;
}

View File

@ -7,9 +7,9 @@ public final class CheckBoxSetting extends SettingsItem
{
private boolean mDefaultValue;
public CheckBoxSetting(String key, String section, int titleId, int descriptionId, boolean defaultValue, Setting setting)
public CheckBoxSetting(String key, String section, int file, int titleId, int descriptionId, boolean defaultValue, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
super(key, section, file, setting, titleId, descriptionId);
mDefaultValue = defaultValue;
}
@ -35,7 +35,7 @@ public final class CheckBoxSetting extends SettingsItem
{
if (getSetting() == null)
{
BooleanSetting setting = new BooleanSetting(getKey(), getSection(), checked);
BooleanSetting setting = new BooleanSetting(getKey(), getSection(), getFile(), checked);
setSetting(setting);
return setting;
}

View File

@ -6,7 +6,7 @@ public final class HeaderSetting extends SettingsItem
{
public HeaderSetting(String key, Setting setting, int titleId, int descriptionId)
{
super(key, null, setting, titleId, descriptionId);
super(key, null, 0, setting, titleId, descriptionId);
}
@Override

View File

@ -19,6 +19,7 @@ public abstract class SettingsItem
private String mKey;
private String mSection;
private int mFile;
private Setting mSetting;
@ -35,10 +36,11 @@ public abstract class SettingsItem
* @param nameId Resource ID for a text string to be displayed as this setting's name.
* @param descriptionId Resource ID for a text string to be displayed as this setting's description.
*/
public SettingsItem(String key, String section, Setting setting, int nameId, int descriptionId)
public SettingsItem(String key, String section, int file, Setting setting, int nameId, int descriptionId)
{
mKey = key;
mSection = section;
mFile = file;
mSetting = setting;
mNameId = nameId;
mDescriptionId = descriptionId;
@ -62,6 +64,15 @@ public abstract class SettingsItem
return mSection;
}
/**
*
* @return The file the backing Setting is saved to.
*/
public int getFile()
{
return mFile;
}
/**
*
* @return The backing Setting, possibly null.

View File

@ -10,9 +10,9 @@ public final class SingleChoiceSetting extends SettingsItem
private int mChoicesId;
private int mValuesId;
public SingleChoiceSetting(String key, String section, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting)
public SingleChoiceSetting(String key, String section, int file, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
super(key, section, file, setting, titleId, descriptionId);
mValuesId = valuesId;
mChoicesId = choicesId;
mDefaultValue = defaultValue;
@ -52,7 +52,7 @@ public final class SingleChoiceSetting extends SettingsItem
{
if (getSetting() == null)
{
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
IntSetting setting = new IntSetting(getKey(), getSection(), getFile(), selection);
setSetting(setting);
return setting;
}

View File

@ -13,9 +13,9 @@ public final class SliderSetting extends SettingsItem
private String mUnits;
public SliderSetting(String key, String section, int titleId, int descriptionId, int max, String units, int defaultValue, Setting setting)
public SliderSetting(String key, String section, int file, int titleId, int descriptionId, int max, String units, int defaultValue, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
super(key, section, file, setting, titleId, descriptionId);
mMax = max;
mUnits = units;
mDefaultValue = defaultValue;
@ -70,7 +70,7 @@ public final class SliderSetting extends SettingsItem
{
if (getSetting() == null)
{
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
IntSetting setting = new IntSetting(getKey(), getSection(), getFile(), selection);
setSetting(setting);
return setting;
}
@ -93,7 +93,7 @@ public final class SliderSetting extends SettingsItem
{
if (getSetting() == null)
{
FloatSetting setting = new FloatSetting(getKey(), getSection(), selection);
FloatSetting setting = new FloatSetting(getKey(), getSection(), getFile(), selection);
setSetting(setting);
return setting;
}

View File

@ -8,7 +8,7 @@ public final class SubmenuSetting extends SettingsItem
public SubmenuSetting(String key, Setting setting, int titleId, int descriptionId, String menuKey)
{
super(key, null, setting, titleId, descriptionId);
super(key, null, 0, setting, titleId, descriptionId);
mMenuKey = menuKey;
}

View File

@ -14,6 +14,7 @@ import org.dolphinemu.dolphinemu.BuildConfig;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
import java.util.ArrayList;
import java.util.HashMap;
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
@ -98,19 +99,19 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
}
@Override
public HashMap<String, SettingSection> getSettings()
public HashMap<String, SettingSection> getSettings(int file)
{
return mPresenter.getSettings();
return mPresenter.getSettings(file);
}
@Override
public void setSettings(HashMap<String, SettingSection> settings)
public void setSettings(ArrayList<HashMap<String, SettingSection>> settings)
{
mPresenter.setSettings(settings);
}
@Override
public void onSettingsFileLoaded(HashMap<String, SettingSection> settings)
public void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings)
{
SettingsFragmentView fragment = getFragment();

View File

@ -8,20 +8,16 @@ import org.dolphinemu.dolphinemu.model.settings.SettingSection;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.util.ArrayList;
import java.util.HashMap;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
public final class SettingsActivityPresenter
{
private static final String SHOULD_SAVE = BuildConfig.APPLICATION_ID + ".should_save";
private SettingsActivityView mView;
private String mFileName;
private HashMap<String, SettingSection> mSettingsBySection;
private ArrayList<HashMap<String, SettingSection>> mSettings = new ArrayList<>();
private int mStackCount;
@ -32,48 +28,16 @@ public final class SettingsActivityPresenter
mView = view;
}
public void onCreate(Bundle savedInstanceState, final String filename)
public void onCreate(Bundle savedInstanceState, String menuTag)
{
mFileName = filename;
if (savedInstanceState == null)
{
// TODO DI should be able to get rid of this hack
if (filename.equals(SettingsFile.FILE_NAME_GCPAD))
{
// Psyche! Don't actually load that file (yet).
mFileName = SettingsFile.FILE_NAME_DOLPHIN;
mView.showSettingsFragment(menuTag, false);
// But do display its fragment, as if we had.
mView.showSettingsFragment(SettingsFile.FILE_NAME_GCPAD, false);
}
else
{
mFileName = filename;
mView.showSettingsFragment(mFileName, false);
}
SettingsFile.readFile(mFileName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<HashMap<String, SettingSection>>()
{
@Override
public void call(HashMap<String, SettingSection> settingsBySection)
{
mSettingsBySection = settingsBySection;
mView.onSettingsFileLoaded(settingsBySection);
}
},
new Action1<Throwable>()
{
@Override
public void call(Throwable throwable)
{
Log.error("[SettingsActivityPresenter] Error reading file " + filename + ".ini: "+ throwable.getMessage());
mView.onSettingsFileNotFound();
}
});
mSettings.add(SettingsFile.SETTINGS_DOLPHIN, SettingsFile.readFile(SettingsFile.FILE_NAME_DOLPHIN, mView));
mSettings.add(SettingsFile.SETTINGS_GFX, SettingsFile.readFile(SettingsFile.FILE_NAME_GFX, mView));
mSettings.add(SettingsFile.SETTINGS_WIIMOTE, SettingsFile.readFile(SettingsFile.FILE_NAME_WIIMOTE, mView));
mView.onSettingsFileLoaded(mSettings);
}
else
{
@ -81,40 +45,25 @@ public final class SettingsActivityPresenter
}
}
public void setSettings(HashMap<String, SettingSection> settings)
public void setSettings(ArrayList<HashMap<String, SettingSection>> settings)
{
mSettingsBySection = settings;
mSettings = settings;
}
public HashMap<String, SettingSection> getSettings()
public HashMap<String, SettingSection> getSettings(int file)
{
return mSettingsBySection;
return mSettings.get(file);
}
public void onStop(boolean finishing)
{
if (mSettingsBySection != null && finishing && mShouldSave)
if (mSettings != null && finishing && mShouldSave)
{
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
SettingsFile.saveFile(mFileName, mSettingsBySection)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Boolean>()
{
@Override
public void call(Boolean aBoolean)
{
mView.showToastMessage("Saved successfully to " + mFileName + ".ini");
}
},
new Action1<Throwable>()
{
@Override
public void call(Throwable throwable)
{
mView.showToastMessage("Error saving " + mFileName + ".ini: " + throwable.getMessage());
}
});
SettingsFile.saveFile(SettingsFile.FILE_NAME_DOLPHIN, mSettings.get(SettingsFile.SETTINGS_DOLPHIN), mView);
SettingsFile.saveFile(SettingsFile.FILE_NAME_GFX, mSettings.get(SettingsFile.SETTINGS_GFX), mView);
SettingsFile.saveFile(SettingsFile.FILE_NAME_WIIMOTE, mSettings.get(SettingsFile.SETTINGS_WIIMOTE), mView);
mView.showToastMessage("Saved settings to INI files");
}
}

View File

@ -2,6 +2,7 @@ package org.dolphinemu.dolphinemu.ui.settings;
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
import java.util.ArrayList;
import java.util.HashMap;
/**
@ -18,29 +19,30 @@ public interface SettingsActivityView
void showSettingsFragment(String menuTag, boolean addToStack);
/**
* Called by a contained Fragment to get access to the Setting Hashmap
* Called by a contained Fragment to get access to the Setting HashMap
* loaded from disk, so that each Fragment doesn't need to perform its own
* read operation.
*
* @return A possibly null Hashmap of Settings.
* @param file The settings file to load.
* @return A possibly null HashMap of Settings.
*/
HashMap<String, SettingSection> getSettings();
HashMap<String, SettingSection> getSettings(int file);
/**
* Used to provide the Activity with a Settings Hashmap if a Fragment already
* Used to provide the Activity with Settings HashMaps if a Fragment already
* has one; for example, if a rotation occurs, the Fragment will not be killed,
* but the Activity will, so the Activity needs to have its Hashmap resupplied.
* but the Activity will, so the Activity needs to have its HashMaps resupplied.
*
* @param settings The Fragment's Settings hashmap.
* @param settings The ArrayList of all the Settings HashMaps.
*/
void setSettings(HashMap<String, SettingSection> settings);
void setSettings(ArrayList<HashMap<String, SettingSection>> settings);
/**
* Called when an asynchronous load operation completes.
*
* @param settings The (possibly null) result of the load operation.
* @param settings The (possibly null) result of the ini load operation.
*/
void onSettingsFileLoaded(HashMap<String, SettingSection> settings);
void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings);
/**
* Called when an asynchronous load operation fails.

View File

@ -132,7 +132,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
if (item.getKey().equals(SettingsFile.KEY_SKIP_EFB) || item.getKey().equals(SettingsFile.KEY_IGNORE_FORMAT))
{
mView.putSetting(new BooleanSetting(item.getKey(), item.getSection(), !checked));
mView.putSetting(new BooleanSetting(item.getKey(), item.getSection(), item.getFile(), !checked));
}
mView.onSettingChanged();
@ -334,19 +334,19 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
switch (which)
{
case 0:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, "OGL");
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, "OGL");
break;
case 1:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, "Vulkan");
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, "Vulkan");
break;
case 2:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, "SW");
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, "SW");
break;
case 3:
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, "Null");
gfxBackend = new StringSetting(SettingsFile.KEY_VIDEO_BACKEND, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, "Null");
break;
}
@ -361,18 +361,18 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
switch (which)
{
case 0:
xfbEnable = new BooleanSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_SETTINGS, false);
xfbReal = new BooleanSetting(SettingsFile.KEY_XFB_REAL, SettingsFile.SECTION_GFX_SETTINGS, false);
xfbEnable = new BooleanSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, false);
xfbReal = new BooleanSetting(SettingsFile.KEY_XFB_REAL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, false);
break;
case 1:
xfbEnable = new BooleanSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_SETTINGS, true);
xfbReal = new BooleanSetting(SettingsFile.KEY_XFB_REAL, SettingsFile.SECTION_GFX_SETTINGS, false);
xfbEnable = new BooleanSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, true);
xfbReal = new BooleanSetting(SettingsFile.KEY_XFB_REAL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, false);
break;
case 2:
xfbEnable = new BooleanSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_SETTINGS, true);
xfbReal = new BooleanSetting(SettingsFile.KEY_XFB_REAL, SettingsFile.SECTION_GFX_SETTINGS, true);
xfbEnable = new BooleanSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, true);
xfbReal = new BooleanSetting(SettingsFile.KEY_XFB_REAL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, true);
break;
}

View File

@ -17,6 +17,7 @@ import org.dolphinemu.dolphinemu.model.settings.Setting;
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
import org.dolphinemu.dolphinemu.ui.DividerItemDecoration;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
import java.util.ArrayList;
import java.util.HashMap;
@ -83,7 +84,11 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), null));
SettingsActivityView activity = (SettingsActivityView) getActivity();
HashMap<String, SettingSection> settings = activity.getSettings();
ArrayList<HashMap<String, SettingSection>> settings = new ArrayList<>();
settings.add(SettingsFile.SETTINGS_DOLPHIN, activity.getSettings(SettingsFile.SETTINGS_DOLPHIN));
settings.add(SettingsFile.SETTINGS_GFX, activity.getSettings(SettingsFile.SETTINGS_GFX));
settings.add(SettingsFile.SETTINGS_WIIMOTE, activity.getSettings(SettingsFile.SETTINGS_WIIMOTE));
mPresenter.onViewCreated(settings);
}
@ -101,13 +106,13 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
}
@Override
public void onSettingsFileLoaded(HashMap<String, SettingSection> settings)
public void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings)
{
mPresenter.setSettings(settings);
}
@Override
public void passSettingsToActivity(HashMap<String, SettingSection> settings)
public void passSettingsToActivity(ArrayList<HashMap<String, SettingSection>> settings)
{
if (mActivity != null)
{

View File

@ -24,7 +24,7 @@ public final class SettingsFragmentPresenter
private String mMenuTag;
private HashMap<String, SettingSection> mSettings;
private ArrayList<HashMap<String, SettingSection>> mSettings;
private ArrayList<SettingsItem> mSettingsList;
private int mGcPadNumber;
@ -47,7 +47,7 @@ public final class SettingsFragmentPresenter
}
}
public void onViewCreated(HashMap<String, SettingSection> settings)
public void onViewCreated(ArrayList<HashMap<String, SettingSection>> settings)
{
setSettings(settings);
}
@ -67,7 +67,7 @@ public final class SettingsFragmentPresenter
public void putSetting(Setting setting)
{
mSettings.get(setting.getSection()).putSetting(setting.getKey(), setting);
mSettings.get(setting.getFile()).get(setting.getSection()).putSetting(setting);
}
public void loadDefaultSettings()
@ -75,7 +75,7 @@ public final class SettingsFragmentPresenter
loadSettingsList();
}
public void setSettings(HashMap<String, SettingSection> settings)
public void setSettings(ArrayList<HashMap<String, SettingSection>> settings)
{
if (mSettingsList == null && settings != null)
{
@ -138,89 +138,80 @@ public final class SettingsFragmentPresenter
Setting dualCore = null;
Setting overclockEnable = null;
Setting overclock = null;
IntSetting videoBackend = new IntSetting(SettingsFile.KEY_VIDEO_BACKEND_INDEX, SettingsFile.SECTION_CORE, getVideoBackendValue());
Setting continuousScan = null;
Setting wiimoteSpeaker = null;
if (mSettings != null)
if (!mSettings.get(SettingsFile.SETTINGS_DOLPHIN).isEmpty())
{
cpuCore = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_CPU_CORE);
dualCore = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_DUAL_CORE);
overclockEnable = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_OVERCLOCK_ENABLE);
overclock = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_OVERCLOCK_PERCENT);
continuousScan = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_WIIMOTE_SCAN);
wiimoteSpeaker = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_WIIMOTE_SPEAKER);
cpuCore = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_CPU_CORE);
dualCore = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_DUAL_CORE);
overclockEnable = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_OVERCLOCK_ENABLE);
overclock = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_OVERCLOCK_PERCENT);
continuousScan = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_WIIMOTE_SCAN);
wiimoteSpeaker = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_WIIMOTE_SPEAKER);
}
else
{
mSettings = new HashMap<>();
mSettings.put(SettingsFile.SECTION_CORE, new SettingSection(SettingsFile.SECTION_CORE));
mSettings.get(SettingsFile.SETTINGS_DOLPHIN).put(SettingsFile.SECTION_CORE, new SettingSection(SettingsFile.SECTION_CORE));
mView.passSettingsToActivity(mSettings);
}
// TODO Set default value for cpuCore based on arch.
sl.add(new SingleChoiceSetting(SettingsFile.KEY_CPU_CORE, SettingsFile.SECTION_CORE, R.string.cpu_core, 0, R.array.emuCoresEntries, R.array.emuCoresValues, 4, cpuCore));
sl.add(new CheckBoxSetting(SettingsFile.KEY_DUAL_CORE, SettingsFile.SECTION_CORE, R.string.dual_core, R.string.dual_core_descrip, true, dualCore));
sl.add(new CheckBoxSetting(SettingsFile.KEY_OVERCLOCK_ENABLE, SettingsFile.SECTION_CORE, R.string.overclock_enable, R.string.overclock_enable_description, false, overclockEnable));
sl.add(new SliderSetting(SettingsFile.KEY_OVERCLOCK_PERCENT, SettingsFile.SECTION_CORE, R.string.overclock_title, 0, 400, "%", 100, overclock));
// While it doesn't seem appropriate to store the video backend with the CPU settings, the video
// backend is stored in the main INI, which can't be changed by the graphics settings page, so
// we have to put it here.
sl.add(new SingleChoiceSetting(SettingsFile.KEY_VIDEO_BACKEND_INDEX, SettingsFile.SECTION_CORE, R.string.video_backend, R.string.video_backend_descrip,
R.array.videoBackendEntries, R.array.videoBackendValues, 0, videoBackend));
sl.add(new CheckBoxSetting(SettingsFile.KEY_WIIMOTE_SCAN, SettingsFile.SECTION_CORE, R.string.wiimote_scanning, R.string.wiimote_scanning_description, true, continuousScan));
sl.add(new CheckBoxSetting(SettingsFile.KEY_WIIMOTE_SPEAKER, SettingsFile.SECTION_CORE, R.string.wiimote_speaker, R.string.wiimote_speaker_description, true, wiimoteSpeaker));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_CPU_CORE, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.cpu_core, 0, R.array.emuCoresEntries, R.array.emuCoresValues, 4, cpuCore));
sl.add(new CheckBoxSetting(SettingsFile.KEY_DUAL_CORE, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.dual_core, R.string.dual_core_descrip, true, dualCore));
sl.add(new CheckBoxSetting(SettingsFile.KEY_OVERCLOCK_ENABLE, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.overclock_enable, R.string.overclock_enable_description, false, overclockEnable));
sl.add(new SliderSetting(SettingsFile.KEY_OVERCLOCK_PERCENT, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.overclock_title, 0, 400, "%", 100, overclock));
sl.add(new CheckBoxSetting(SettingsFile.KEY_WIIMOTE_SCAN, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.wiimote_scanning, R.string.wiimote_scanning_description, true, continuousScan));
sl.add(new CheckBoxSetting(SettingsFile.KEY_WIIMOTE_SPEAKER, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.wiimote_speaker, R.string.wiimote_speaker_description, true, wiimoteSpeaker));
}
private void addGcPadSettings(ArrayList<SettingsItem> sl)
{
if (mSettings != null)
if (!mSettings.get(SettingsFile.SETTINGS_DOLPHIN).isEmpty())
{
for (int i = 0; i < 4; i++)
{
// TODO This controller_0 + i business is quite the hack. It should work, but only if the definitions are kept together and in order.
Setting gcPadSetting = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_GCPAD_TYPE + i);
sl.add(new SingleChoiceSetting(SettingsFile.KEY_GCPAD_TYPE + i, SettingsFile.SECTION_CORE, R.string.controller_0 + i, 0, R.array.gcpadTypeEntries, R.array.gcpadTypeValues, 0, gcPadSetting));
Setting gcPadSetting = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_GCPAD_TYPE + i);
sl.add(new SingleChoiceSetting(SettingsFile.KEY_GCPAD_TYPE + i, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.controller_0 + i, 0, R.array.gcpadTypeEntries, R.array.gcpadTypeValues, 0, gcPadSetting));
}
}
}
private void addWiimoteSettings(ArrayList<SettingsItem> sl)
{
if (mSettings != null)
if (!mSettings.get(SettingsFile.SETTINGS_WIIMOTE).isEmpty())
{
for (int i = 1; i <= 4; i++)
{
// TODO This wiimote_0 + i business is quite the hack. It should work, but only if the definitions are kept together and in order.
Setting wiimoteSetting = mSettings.get(SettingsFile.SECTION_WIIMOTE + i).getSetting(SettingsFile.KEY_WIIMOTE_TYPE);
sl.add(new SingleChoiceSetting(SettingsFile.KEY_WIIMOTE_TYPE, SettingsFile.SECTION_WIIMOTE + i, R.string.wiimote_0 + i - 1, 0, R.array.wiimoteTypeEntries, R.array.wiimoteTypeValues, 0, wiimoteSetting));
Setting wiimoteSetting = mSettings.get(SettingsFile.SETTINGS_WIIMOTE).get(SettingsFile.SECTION_WIIMOTE + i).getSetting(SettingsFile.KEY_WIIMOTE_TYPE);
sl.add(new SingleChoiceSetting(SettingsFile.KEY_WIIMOTE_TYPE, SettingsFile.SECTION_WIIMOTE + i, SettingsFile.SETTINGS_WIIMOTE, R.string.wiimote_0 + i - 1, 0, R.array.wiimoteTypeEntries, R.array.wiimoteTypeValues, 0, wiimoteSetting));
}
}
}
private void addGraphicsSettings(ArrayList<SettingsItem> sl)
{
IntSetting videoBackend = new IntSetting(SettingsFile.KEY_VIDEO_BACKEND_INDEX, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, getVideoBackendValue());
Setting showFps = null;
if (mSettings != null)
if (!mSettings.get(SettingsFile.SETTINGS_GFX).isEmpty())
{
showFps = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_SHOW_FPS);
showFps = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_SHOW_FPS);
}
else
{
mSettings = new HashMap<>();
mSettings.put(SettingsFile.SECTION_GFX_SETTINGS, new SettingSection(SettingsFile.SECTION_GFX_SETTINGS));
mSettings.put(SettingsFile.SECTION_GFX_ENHANCEMENTS, new SettingSection(SettingsFile.SECTION_GFX_ENHANCEMENTS));
mSettings.put(SettingsFile.SECTION_GFX_HACKS, new SettingSection(SettingsFile.SECTION_GFX_HACKS));
mSettings.get(SettingsFile.SETTINGS_GFX).put(SettingsFile.SECTION_GFX_SETTINGS, new SettingSection(SettingsFile.SECTION_GFX_SETTINGS));
mSettings.get(SettingsFile.SETTINGS_GFX).put(SettingsFile.SECTION_GFX_ENHANCEMENTS, new SettingSection(SettingsFile.SECTION_GFX_ENHANCEMENTS));
mSettings.get(SettingsFile.SETTINGS_GFX).put(SettingsFile.SECTION_GFX_HACKS, new SettingSection(SettingsFile.SECTION_GFX_HACKS));
mView.passSettingsToActivity(mSettings);
}
sl.add(new CheckBoxSetting(SettingsFile.KEY_SHOW_FPS, SettingsFile.SECTION_GFX_SETTINGS, R.string.show_fps, 0, true, showFps));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_VIDEO_BACKEND_INDEX, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.video_backend, R.string.video_backend_descrip, R.array.videoBackendEntries, R.array.videoBackendValues, 0, videoBackend));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SHOW_FPS, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.show_fps, 0, true, showFps));
sl.add(new SubmenuSetting(null, null, R.string.enhancements, 0, SettingsFile.SECTION_GFX_ENHANCEMENTS));
sl.add(new SubmenuSetting(null, null, R.string.hacks, 0, SettingsFile.SECTION_GFX_HACKS));
@ -228,26 +219,26 @@ public final class SettingsFragmentPresenter
private void addEnhanceSettings(ArrayList<SettingsItem> sl)
{
Setting resolution = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_INTERNAL_RES);
Setting fsaa = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_FSAA);
Setting anisotropic = mSettings.get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_ANISOTROPY);
Setting efbScaledCopy = mSettings.get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_SCALED_EFB);
Setting perPixel = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_PER_PIXEL);
Setting forceFilter = mSettings.get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_FORCE_FILTERING);
Setting disableFog = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_DISABLE_FOG);
Setting resolution = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_INTERNAL_RES);
Setting fsaa = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_FSAA);
Setting anisotropic = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_ANISOTROPY);
Setting efbScaledCopy = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_SCALED_EFB);
Setting perPixel = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_PER_PIXEL);
Setting forceFilter = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_FORCE_FILTERING);
Setting disableFog = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_DISABLE_FOG);
sl.add(new SingleChoiceSetting(SettingsFile.KEY_INTERNAL_RES, SettingsFile.SECTION_GFX_SETTINGS, R.string.internal_resolution, R.string.internal_resolution_descrip, R.array.internalResolutionEntries, R.array.internalResolutionValues, 0, resolution));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_FSAA, SettingsFile.SECTION_GFX_SETTINGS, R.string.FSAA, R.string.FSAA_descrip, R.array.FSAAEntries, R.array.FSAAValues, 0, fsaa));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_ANISOTROPY, SettingsFile.SECTION_GFX_ENHANCEMENTS, R.string.anisotropic_filtering, R.string.anisotropic_filtering_descrip, R.array.anisotropicFilteringEntries, R.array.anisotropicFilteringValues, 0, anisotropic));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_INTERNAL_RES, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.internal_resolution, R.string.internal_resolution_descrip, R.array.internalResolutionEntries, R.array.internalResolutionValues, 0, resolution));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_FSAA, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.FSAA, R.string.FSAA_descrip, R.array.FSAAEntries, R.array.FSAAValues, 0, fsaa));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_ANISOTROPY, SettingsFile.SECTION_GFX_ENHANCEMENTS, SettingsFile.SETTINGS_GFX, R.string.anisotropic_filtering, R.string.anisotropic_filtering_descrip, R.array.anisotropicFilteringEntries, R.array.anisotropicFilteringValues, 0, anisotropic));
// TODO
// Setting shader = mSettings.get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_POST_SHADER)
// Setting shader = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_ENHANCEMENTS).getSetting(SettingsFile.KEY_POST_SHADER)
// sl.add(new SingleChoiceSetting(.getKey(), , R.string., R.string._descrip, R.array., R.array.));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SCALED_EFB, SettingsFile.SECTION_GFX_HACKS, R.string.scaled_efb_copy, R.string.scaled_efb_copy_descrip, true, efbScaledCopy));
sl.add(new CheckBoxSetting(SettingsFile.KEY_PER_PIXEL, SettingsFile.SECTION_GFX_SETTINGS, R.string.per_pixel_lighting, R.string.per_pixel_lighting_descrip, false, perPixel));
sl.add(new CheckBoxSetting(SettingsFile.KEY_FORCE_FILTERING, SettingsFile.SECTION_GFX_ENHANCEMENTS, R.string.force_texture_filtering, R.string.force_texture_filtering_descrip, false, forceFilter));
sl.add(new CheckBoxSetting(SettingsFile.KEY_DISABLE_FOG, SettingsFile.SECTION_GFX_SETTINGS, R.string.disable_fog, R.string.disable_fog_descrip, false, disableFog));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SCALED_EFB, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.scaled_efb_copy, R.string.scaled_efb_copy_descrip, true, efbScaledCopy));
sl.add(new CheckBoxSetting(SettingsFile.KEY_PER_PIXEL, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.per_pixel_lighting, R.string.per_pixel_lighting_descrip, false, perPixel));
sl.add(new CheckBoxSetting(SettingsFile.KEY_FORCE_FILTERING, SettingsFile.SECTION_GFX_ENHANCEMENTS, SettingsFile.SETTINGS_GFX, R.string.force_texture_filtering, R.string.force_texture_filtering_descrip, false, forceFilter));
sl.add(new CheckBoxSetting(SettingsFile.KEY_DISABLE_FOG, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.disable_fog, R.string.disable_fog_descrip, false, disableFog));
/*
Check if we support stereo
@ -265,48 +256,48 @@ public final class SettingsFragmentPresenter
private void addHackSettings(ArrayList<SettingsItem> sl)
{
boolean skipEFBValue = getInvertedBooleanValue(SettingsFile.SECTION_GFX_HACKS, SettingsFile.KEY_SKIP_EFB, false);
boolean ignoreFormatValue = getInvertedBooleanValue(SettingsFile.SECTION_GFX_HACKS, SettingsFile.KEY_IGNORE_FORMAT, true);
boolean skipEFBValue = getInvertedBooleanValue(SettingsFile.SETTINGS_GFX, SettingsFile.SECTION_GFX_HACKS, SettingsFile.KEY_SKIP_EFB, false);
boolean ignoreFormatValue = getInvertedBooleanValue(SettingsFile.SETTINGS_GFX, SettingsFile.SECTION_GFX_HACKS, SettingsFile.KEY_IGNORE_FORMAT, true);
int xfbValue = getXfbValue();
BooleanSetting skipEFB = new BooleanSetting(SettingsFile.KEY_SKIP_EFB, SettingsFile.SECTION_GFX_HACKS, skipEFBValue);
BooleanSetting ignoreFormat = new BooleanSetting(SettingsFile.KEY_IGNORE_FORMAT, SettingsFile.SECTION_GFX_HACKS, ignoreFormatValue);
Setting efbToTexture = mSettings.get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_EFB_TEXTURE);
Setting texCacheAccuracy = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_TEXCACHE_ACCURACY);
IntSetting xfb = new IntSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_HACKS, xfbValue);
Setting fastDepth = mSettings.get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_FAST_DEPTH);
Setting aspectRatio = mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_ASPECT_RATIO);
BooleanSetting skipEFB = new BooleanSetting(SettingsFile.KEY_SKIP_EFB, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, skipEFBValue);
BooleanSetting ignoreFormat = new BooleanSetting(SettingsFile.KEY_IGNORE_FORMAT, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, ignoreFormatValue);
Setting efbToTexture = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_EFB_TEXTURE);
Setting texCacheAccuracy = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_TEXCACHE_ACCURACY);
IntSetting xfb = new IntSetting(SettingsFile.KEY_XFB, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, xfbValue);
Setting fastDepth = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_FAST_DEPTH);
Setting aspectRatio = mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_ASPECT_RATIO);
sl.add(new HeaderSetting(null, null, R.string.embedded_frame_buffer, 0));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SKIP_EFB, SettingsFile.SECTION_GFX_HACKS, R.string.skip_efb_access, R.string.skip_efb_access_descrip, false, skipEFB));
sl.add(new CheckBoxSetting(SettingsFile.KEY_IGNORE_FORMAT, SettingsFile.SECTION_GFX_HACKS, R.string.ignore_format_changes, R.string.ignore_format_changes_descrip, true, ignoreFormat));
sl.add(new CheckBoxSetting(SettingsFile.KEY_EFB_TEXTURE, SettingsFile.SECTION_GFX_HACKS, R.string.efb_copy_method, R.string.efb_copy_method_descrip, true, efbToTexture));
sl.add(new CheckBoxSetting(SettingsFile.KEY_SKIP_EFB, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.skip_efb_access, R.string.skip_efb_access_descrip, false, skipEFB));
sl.add(new CheckBoxSetting(SettingsFile.KEY_IGNORE_FORMAT, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.ignore_format_changes, R.string.ignore_format_changes_descrip, true, ignoreFormat));
sl.add(new CheckBoxSetting(SettingsFile.KEY_EFB_TEXTURE, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.efb_copy_method, R.string.efb_copy_method_descrip, true, efbToTexture));
sl.add(new HeaderSetting(null, null, R.string.texture_cache, 0));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_TEXCACHE_ACCURACY, SettingsFile.SECTION_GFX_SETTINGS, R.string.texture_cache_accuracy, R.string.texture_cache_accuracy_descrip, R.array.textureCacheAccuracyEntries, R.array.textureCacheAccuracyValues, 128, texCacheAccuracy));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_TEXCACHE_ACCURACY, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.texture_cache_accuracy, R.string.texture_cache_accuracy_descrip, R.array.textureCacheAccuracyEntries, R.array.textureCacheAccuracyValues, 128, texCacheAccuracy));
sl.add(new HeaderSetting(null, null, R.string.external_frame_buffer, 0));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_XFB_METHOD, SettingsFile.SECTION_GFX_HACKS, R.string.external_frame_buffer, R.string.external_frame_buffer_descrip, R.array.externalFrameBufferEntries, R.array.externalFrameBufferValues, 0, xfb));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_XFB_METHOD, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.external_frame_buffer, R.string.external_frame_buffer_descrip, R.array.externalFrameBufferEntries, R.array.externalFrameBufferValues, 0, xfb));
sl.add(new HeaderSetting(null, null, R.string.other, 0));
sl.add(new CheckBoxSetting(SettingsFile.KEY_FAST_DEPTH, SettingsFile.SECTION_GFX_HACKS, R.string.fast_depth_calculation, R.string.fast_depth_calculation_descrip, true, fastDepth));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_ASPECT_RATIO, SettingsFile.SECTION_GFX_SETTINGS, R.string.aspect_ratio, R.string.aspect_ratio_descrip, R.array.aspectRatioEntries, R.array.aspectRatioValues, 0, aspectRatio));
sl.add(new CheckBoxSetting(SettingsFile.KEY_FAST_DEPTH, SettingsFile.SECTION_GFX_HACKS, SettingsFile.SETTINGS_GFX, R.string.fast_depth_calculation, R.string.fast_depth_calculation_descrip, true, fastDepth));
sl.add(new SingleChoiceSetting(SettingsFile.KEY_ASPECT_RATIO, SettingsFile.SECTION_GFX_SETTINGS, SettingsFile.SETTINGS_GFX, R.string.aspect_ratio, R.string.aspect_ratio_descrip, R.array.aspectRatioEntries, R.array.aspectRatioValues, 0, aspectRatio));
}
private void addGcAdapterSettings(ArrayList<SettingsItem> sl, int gcPadNumber)
{
Setting rumble = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber);
Setting bongos = mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber);
Setting rumble = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber);
Setting bongos = mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber);
sl.add(new CheckBoxSetting(SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber, SettingsFile.SECTION_CORE, R.string.gc_adapter_rumble, R.string.gc_adapter_rumble_description, false, rumble));
sl.add(new CheckBoxSetting(SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber, SettingsFile.SECTION_CORE, R.string.gc_adapter_bongos, R.string.gc_adapter_bongos_description, false, bongos));
sl.add(new CheckBoxSetting(SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.gc_adapter_rumble, R.string.gc_adapter_rumble_description, false, rumble));
sl.add(new CheckBoxSetting(SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber, SettingsFile.SECTION_CORE, SettingsFile.SETTINGS_DOLPHIN, R.string.gc_adapter_bongos, R.string.gc_adapter_bongos_description, false, bongos));
}
private boolean getInvertedBooleanValue(String section, String key, boolean defaultValue)
private boolean getInvertedBooleanValue(int file, String section, String key, boolean defaultValue)
{
try
{
return !((BooleanSetting) mSettings.get(section).getSetting(key)).getValue();
return !((BooleanSetting) mSettings.get(file).get(section).getSetting(key)).getValue();
}
catch (NullPointerException ex)
{
@ -320,7 +311,7 @@ public final class SettingsFragmentPresenter
try
{
String videoBackend = ((StringSetting)mSettings.get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_VIDEO_BACKEND)).getValue();
String videoBackend = ((StringSetting)mSettings.get(SettingsFile.SETTINGS_DOLPHIN).get(SettingsFile.SECTION_CORE).getSetting(SettingsFile.KEY_VIDEO_BACKEND)).getValue();
if (videoBackend.equals("OGL"))
videoBackendValue = 0;
else if (videoBackend.equals("Vulkan"))
@ -346,8 +337,8 @@ public final class SettingsFragmentPresenter
try
{
boolean usingXFB = ((BooleanSetting) mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_XFB)).getValue();
boolean usingRealXFB = ((BooleanSetting) mSettings.get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_XFB_REAL)).getValue();
boolean usingXFB = ((BooleanSetting) mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_XFB)).getValue();
boolean usingRealXFB = ((BooleanSetting) mSettings.get(SettingsFile.SETTINGS_GFX).get(SettingsFile.SECTION_GFX_SETTINGS).getSetting(SettingsFile.KEY_XFB_REAL)).getValue();
if (!usingXFB)
{

View File

@ -19,23 +19,23 @@ public interface SettingsFragmentView
* Called by the containing Activity to notify the Fragment that an
* asynchronous load operation completed.
*
* @param settings The potentially-null result of the load operation.
* @param settings The (possibly null) result of the ini load operation.
*/
void onSettingsFileLoaded(HashMap<String, SettingSection> settings);
void onSettingsFileLoaded(ArrayList<HashMap<String, SettingSection>> settings);
/**
* Pass a settings Hashmap to the containing activity, so that it can
* share the Hashmap with other SettingsFragments; useful so that rotations
* Pass a settings HashMap to the containing activity, so that it can
* share the HashMap with other SettingsFragments; useful so that rotations
* do not require an additional load operation.
*
* @param settings A Hashmap containing all the settings
* @param settings An ArrayList containing all the settings HashMaps.
*/
void passSettingsToActivity(HashMap<String, SettingSection> settings);
void passSettingsToActivity(ArrayList<HashMap<String, SettingSection>> settings);
/**
* Pass an ArrayList to the View so that it can be displayed on screen.
*
* @param settingsList The result of converting the Hashmap to an ArrayList
* @param settingsList The result of converting the HashMap to an ArrayList
*/
void showSettingsList(ArrayList<SettingsItem> settingsList);
@ -66,7 +66,7 @@ public interface SettingsFragmentView
void showToastMessage(String message);
/**
* Have the fragment add a setting to the Hashmap.
* Have the fragment add a setting to the HashMap.
*
* @param setting The (possibly previously missing) new setting.
*/

View File

@ -9,6 +9,7 @@ import org.dolphinemu.dolphinemu.model.settings.IntSetting;
import org.dolphinemu.dolphinemu.model.settings.Setting;
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
import org.dolphinemu.dolphinemu.model.settings.StringSetting;
import org.dolphinemu.dolphinemu.ui.settings.SettingsActivityView;
import java.io.BufferedReader;
import java.io.File;
@ -20,14 +21,15 @@ import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Set;
import rx.Observable;
import rx.Subscriber;
/**
* Contains static methods for interacting with .ini files in which settings are stored.
*/
public final class SettingsFile
{
public static final int SETTINGS_DOLPHIN = 0;
public static final int SETTINGS_GFX = 1;
public static final int SETTINGS_WIIMOTE = 2;
public static final String FILE_NAME_DOLPHIN = "Dolphin";
public static final String FILE_NAME_GFX = "GFX";
public static final String FILE_NAME_GCPAD = "GCPadNew";
@ -92,129 +94,112 @@ public final class SettingsFile
}
/**
* Reads a given .ini file from disk and returns it as an Rx Observable. If successful,
* this Observable emits a Hashmap of SettingSections, themselves effectively a Hashmap of
* key/value settings. If unsuccessful, the observer notifies the subscriber of why it failed.
* Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves
* effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
* failed.
*
* @param fileName The name of the settings file without a path or extension.
* @return An Observable that emits a Hashmap of the file's contents, then completes.
* @param view The current view.
* @return An Observable that emits a HashMap of the file's contents, then completes.
*/
public static Observable<HashMap<String, SettingSection>> readFile(final String fileName)
public static HashMap<String, SettingSection> readFile(final String fileName, SettingsActivityView view)
{
return Observable.create(new Observable.OnSubscribe<HashMap<String, SettingSection>>()
HashMap<String, SettingSection> sections = new HashMap<>();
File ini = getSettingsFile(fileName);
BufferedReader reader = null;
try
{
@Override
public void call(Subscriber<? super HashMap<String, SettingSection>> subscriber)
reader = new BufferedReader(new FileReader(ini));
SettingSection current = null;
for (String line; (line = reader.readLine()) != null; )
{
if (line.startsWith("[") && line.endsWith("]"))
{
current = sectionFromLine(line);
sections.put(current.getName(), current);
}
else if ((current != null) && line.contains("="))
{
Setting setting = settingFromLine(current, line, fileName);
current.putSetting(setting);
}
}
}
catch (FileNotFoundException e)
{
Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.getMessage());
view.onSettingsFileNotFound();
}
catch (IOException e)
{
Log.error("[SettingsFile] Error reading from: " + fileName + ".ini: " + e.getMessage());
view.onSettingsFileNotFound();
}
finally
{
if (reader != null)
{
HashMap<String, SettingSection> sections = new HashMap<>();
File ini = getSettingsFile(fileName);
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(ini));
SettingSection current = null;
for (String line; (line = reader.readLine()) != null; )
{
if (line.startsWith("[") && line.endsWith("]"))
{
current = sectionFromLine(line);
sections.put(current.getName(), current);
}
else if ((current != null) && line.contains("="))
{
Setting setting = settingFromLine(current, line);
current.putSetting(setting.getKey(), setting);
}
}
}
catch (FileNotFoundException e)
{
Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.getMessage());
subscriber.onError(e);
reader.close();
}
catch (IOException e)
{
Log.error("[SettingsFile] Error reading from: " + fileName + ".ini: " + e.getMessage());
subscriber.onError(e);
} finally
{
if (reader != null)
{
try
{
reader.close();
}
catch (IOException e)
{
Log.error("[SettingsFile] Error closing: " + fileName + ".ini: " + e.getMessage());
subscriber.onError(e);
}
}
Log.error("[SettingsFile] Error closing: " + fileName + ".ini: " + e.getMessage());
}
subscriber.onNext(sections);
subscriber.onCompleted();
}
});
}
return sections;
}
/**
* Saves a Settings Hashmap to a given .ini file on disk, returning the operation
* as an Rx Observable. If successful, this Observable emits an event to notify subscribers;
* if unsuccessful, the observer notifies the subscriber of why it failed.
* Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error
* telling why it failed.
*
* @param fileName The target filename without a path or extension.
* @param sections The hashmap containing the Settings we want to serialize.
* @param sections The HashMap containing the Settings we want to serialize.
* @param view The current view.
* @return An Observable representing the operation.
*/
public static Observable<Boolean> saveFile(final String fileName, final HashMap<String, SettingSection> sections)
public static void saveFile(final String fileName, final HashMap<String, SettingSection> sections, SettingsActivityView view)
{
return Observable.create(new Observable.OnSubscribe<Boolean>()
File ini = getSettingsFile(fileName);
PrintWriter writer = null;
try
{
@Override
public void call(Subscriber<? super Boolean> subscriber)
writer = new PrintWriter(ini, "UTF-8");
Set<String> keySet = sections.keySet();
for (String key : keySet)
{
File ini = getSettingsFile(fileName);
PrintWriter writer = null;
try
{
writer = new PrintWriter(ini, "UTF-8");
Set<String> keySet = sections.keySet();
for (String key : keySet)
{
SettingSection section = sections.get(key);
writeSection(writer, section);
}
}
catch (FileNotFoundException e)
{
Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.getMessage());
subscriber.onError(e);
}
catch (UnsupportedEncodingException e)
{
Log.error("[SettingsFile] Bad encoding; please file a bug report: " + fileName + ".ini: " + e.getMessage());
subscriber.onError(e);
} finally
{
if (writer != null)
{
writer.close();
}
}
subscriber.onNext(true);
subscriber.onCompleted();
SettingSection section = sections.get(key);
writeSection(writer, section);
}
});
}
catch (FileNotFoundException e)
{
Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.getMessage());
view.showToastMessage("Error saving " + fileName + ".ini: " + e.getMessage());
}
catch (UnsupportedEncodingException e)
{
Log.error("[SettingsFile] Bad encoding; please file a bug report: " + fileName + ".ini: " + e.getMessage());
view.showToastMessage("Error saving " + fileName + ".ini: " + e.getMessage());
}
finally
{
if (writer != null)
{
writer.close();
}
}
}
@NonNull
@ -234,22 +219,37 @@ public final class SettingsFile
* For a line of text, determines what type of data is being represented, and returns
* a Setting object containing this data.
*
* @param current The section currently being parsed by the consuming method.
* @param line The line of text being parsed.
* @param current The section currently being parsed by the consuming method.
* @param line The line of text being parsed.
* @param fileName The name of the ini file the setting is in.
* @return A typed Setting containing the key/value contained in the line.
*/
private static Setting settingFromLine(SettingSection current, String line)
private static Setting settingFromLine(SettingSection current, String line, String fileName)
{
String[] splitLine = line.split("=");
String key = splitLine[0].trim();
String value = splitLine[1].trim();
int file;
switch (fileName)
{
case FILE_NAME_GFX:
file = SETTINGS_GFX;
break;
case FILE_NAME_WIIMOTE:
file = SETTINGS_WIIMOTE;
break;
default:
file = SETTINGS_DOLPHIN;
break;
}
try
{
int valueAsInt = Integer.valueOf(value);
return new IntSetting(key, current.getName(), valueAsInt);
return new IntSetting(key, current.getName(), file, valueAsInt);
}
catch (NumberFormatException ex)
{
@ -259,7 +259,7 @@ public final class SettingsFile
{
float valueAsFloat = Float.valueOf(value);
return new FloatSetting(key, current.getName(), valueAsFloat);
return new FloatSetting(key, current.getName(), file, valueAsFloat);
}
catch (NumberFormatException ex)
{
@ -268,16 +268,16 @@ public final class SettingsFile
switch (value)
{
case "True":
return new BooleanSetting(key, current.getName(), true);
return new BooleanSetting(key, current.getName(), file, true);
case "False":
return new BooleanSetting(key, current.getName(), false);
return new BooleanSetting(key, current.getName(), file, false);
default:
return new StringSetting(key, current.getName(), value);
return new StringSetting(key, current.getName(), file, value);
}
}
/**
* Writes the contents of a Section hashmap to disk.
* Writes the contents of a Section HashMap to disk.
*
* @param writer A PrintWriter pointed at a file on disk.
* @param section A section containing settings to be written to the file.