Merge pull request #3547 from sigmabeta/android-config-rewrite
[Android] Rewrite settings UI.
@ -9,10 +9,10 @@
|
|||||||
<item>@string/cached_interpreter</item>
|
<item>@string/cached_interpreter</item>
|
||||||
<item>@string/jit_arm64_recompiler</item>
|
<item>@string/jit_arm64_recompiler</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="int_emu_cores" translatable="false">
|
<integer-array name="int_emu_cores" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>5</item>
|
<item>5</item>
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -56,9 +56,9 @@
|
|||||||
android:label="@string/add_directory_title"/>
|
android:label="@string/add_directory_title"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.SettingsActivity"
|
android:name=".ui.settings.SettingsActivity"
|
||||||
android:theme="@style/DolphinSettingsGamecube"
|
android:theme="@style/DolphinSettingsGamecube"
|
||||||
android:label="@string/grid_menu_settings"/>
|
android:label="@string/grid_menu_core_settings"/>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activities.EmulationActivity"
|
android:name=".activities.EmulationActivity"
|
||||||
@ -71,8 +71,6 @@
|
|||||||
|
|
||||||
<service android:name=".services.AssetCopyService"/>
|
<service android:name=".services.AssetCopyService"/>
|
||||||
|
|
||||||
<service android:name=".services.SettingsSaveService"/>
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".model.GameProvider"
|
android:name=".model.GameProvider"
|
||||||
android:authorities="${applicationId}.provider"
|
android:authorities="${applicationId}.provider"
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package org.dolphinemu.dolphinemu.activities;
|
|
||||||
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.fragments.SettingsFragment;
|
|
||||||
import org.dolphinemu.dolphinemu.services.SettingsSaveService;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.Log;
|
|
||||||
|
|
||||||
public final class SettingsActivity extends AppCompatActivity
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// Display the fragment as the main content.
|
|
||||||
getFragmentManager().beginTransaction()
|
|
||||||
.replace(android.R.id.content, new SettingsFragment(), "settings_fragment")
|
|
||||||
.commit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If this is called, the user has left the settings screen (potentially through the
|
|
||||||
* home button) and will expect their changes to be persisted. So we kick off an
|
|
||||||
* IntentService which will do so on a background thread.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onStop()
|
|
||||||
{
|
|
||||||
super.onStop();
|
|
||||||
|
|
||||||
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
|
|
||||||
|
|
||||||
// Copy assets into appropriate locations.
|
|
||||||
Intent settingsSaver = new Intent(this, SettingsSaveService.class);
|
|
||||||
startService(settingsSaver);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void launch(Context context)
|
|
||||||
{
|
|
||||||
Intent settings = new Intent(context, SettingsActivity.class);
|
|
||||||
context.startActivity(settings);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,155 +0,0 @@
|
|||||||
package org.dolphinemu.dolphinemu.fragments;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.preference.ListPreference;
|
|
||||||
import android.preference.PreferenceFragment;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.EGLHelper;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
|
||||||
|
|
||||||
public final class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener
|
|
||||||
{
|
|
||||||
private SharedPreferences mPreferences;
|
|
||||||
private ListPreference mVideoBackendPreference;
|
|
||||||
|
|
||||||
private final EGLHelper mEglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
|
|
||||||
private final String mVendor = mEglHelper.getGL().glGetString(GL10.GL_VENDOR);
|
|
||||||
|
|
||||||
private final String mVersion = mEglHelper.getGL().glGetString(GL10.GL_VERSION);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
// Load the preferences from an XML resource
|
|
||||||
addPreferencesFromResource(R.xml.preferences);
|
|
||||||
|
|
||||||
// TODO Below here is effectively ported from the old VideoSettingsFragment. There is
|
|
||||||
// TODO probably a simpler way to do this, but potentially could require UI discussion/feedback.
|
|
||||||
|
|
||||||
// Setting valid video backends.
|
|
||||||
mVideoBackendPreference = (ListPreference) findPreference("gpuPref");
|
|
||||||
final boolean deviceSupportsGL = mEglHelper.supportsOpenGL();
|
|
||||||
final boolean deviceSupportsGLES3 = mEglHelper.supportsGLES3();
|
|
||||||
|
|
||||||
if (deviceSupportsGL)
|
|
||||||
{
|
|
||||||
mVideoBackendPreference.setEntries(R.array.videoBackendEntriesGL);
|
|
||||||
mVideoBackendPreference.setEntryValues(R.array.videoBackendValuesGL);
|
|
||||||
}
|
|
||||||
else if (deviceSupportsGLES3)
|
|
||||||
{
|
|
||||||
mVideoBackendPreference.setEntries(R.array.videoBackendEntriesGLES3);
|
|
||||||
mVideoBackendPreference.setEntryValues(R.array.videoBackendValuesGLES3);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mVideoBackendPreference.setEntries(R.array.videoBackendEntriesNoGLES3);
|
|
||||||
mVideoBackendPreference.setEntryValues(R.array.videoBackendValuesNoGLES3);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Set available post processing shaders
|
|
||||||
//
|
|
||||||
|
|
||||||
List<CharSequence> shader_names = new ArrayList<CharSequence>();
|
|
||||||
List<CharSequence> shader_values = new ArrayList<CharSequence>();
|
|
||||||
|
|
||||||
// Disabled option
|
|
||||||
shader_names.add("Disabled");
|
|
||||||
shader_values.add("");
|
|
||||||
|
|
||||||
// TODO Since shaders are included with the APK, we know what they are at build-time. We should
|
|
||||||
// TODO be able to run this logic somehow at build-time and not rely on the device doing it.
|
|
||||||
|
|
||||||
File shaders_folder = new File(Environment.getExternalStorageDirectory() + File.separator + "dolphin-emu" + File.separator + "Shaders");
|
|
||||||
if (shaders_folder.exists())
|
|
||||||
{
|
|
||||||
File[] shaders = shaders_folder.listFiles();
|
|
||||||
for (File file : shaders)
|
|
||||||
{
|
|
||||||
if (file.isFile())
|
|
||||||
{
|
|
||||||
String filename = file.getName();
|
|
||||||
if (filename.endsWith(".glsl"))
|
|
||||||
{
|
|
||||||
// Strip the extension and put it in to the list
|
|
||||||
shader_names.add(filename.substring(0, filename.lastIndexOf('.')));
|
|
||||||
shader_values.add(filename.substring(0, filename.lastIndexOf('.')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final ListPreference shader_preference = (ListPreference) findPreference("postProcessingShader");
|
|
||||||
shader_preference.setEntries(shader_names.toArray(new CharSequence[shader_names.size()]));
|
|
||||||
shader_preference.setEntryValues(shader_values.toArray(new CharSequence[shader_values.size()]));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Disable all options if Software Rendering is used.
|
|
||||||
//
|
|
||||||
// Note that the numeric value in 'getPreference()'
|
|
||||||
// denotes the placement on the UI. So if more elements are
|
|
||||||
// added to the video settings, these may need to change.
|
|
||||||
//
|
|
||||||
mPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
|
||||||
|
|
||||||
if (mVideoBackendPreference.getValue().equals("Software Renderer"))
|
|
||||||
{
|
|
||||||
findPreference("enhancements").setEnabled(false);
|
|
||||||
findPreference("hacks").setEnabled(false);
|
|
||||||
findPreference("showFPS").setEnabled(false);
|
|
||||||
}
|
|
||||||
else if (mVideoBackendPreference.getValue().equals("OGL"))
|
|
||||||
{
|
|
||||||
findPreference("enhancements").setEnabled(true);
|
|
||||||
findPreference("hacks").setEnabled(true);
|
|
||||||
findPreference("showFPS").setEnabled(true);
|
|
||||||
|
|
||||||
// Check if we support stereo
|
|
||||||
// If we support desktop GL then we must support at least OpenGL 3.2
|
|
||||||
// If we only support OpenGLES then we need both OpenGLES 3.1 and AEP
|
|
||||||
if ((mEglHelper.supportsOpenGL() && mEglHelper.GetVersion() >= 320) ||
|
|
||||||
(mEglHelper.supportsGLES3() && mEglHelper.GetVersion() >= 310 && mEglHelper.SupportsExtension("GL_ANDROID_extension_pack_es31a")))
|
|
||||||
findPreference("StereoscopyScreen").setEnabled(true);
|
|
||||||
else
|
|
||||||
findPreference("StereoscopyScreen").setEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also set a listener, so that if someone changes the video backend, it will disable
|
|
||||||
// the video settings, upon the user choosing "Software Rendering".
|
|
||||||
mPreferences.registerOnSharedPreferenceChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences preferences, String key)
|
|
||||||
{
|
|
||||||
if (key.equals("gpuPref"))
|
|
||||||
{
|
|
||||||
if (preferences.getString(key, "Software Renderer").equals("Software Renderer"))
|
|
||||||
{
|
|
||||||
findPreference("enhancements").setEnabled(false);
|
|
||||||
findPreference("hacks").setEnabled(false);
|
|
||||||
findPreference("showFPS").setEnabled(false);
|
|
||||||
}
|
|
||||||
else if (preferences.getString(key, "Software Renderer").equals("OGL"))
|
|
||||||
{
|
|
||||||
findPreference("enhancements").setEnabled(true);
|
|
||||||
findPreference("hacks").setEnabled(true);
|
|
||||||
findPreference("showFPS").setEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,28 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings;
|
||||||
|
|
||||||
|
public final class BooleanSetting extends Setting
|
||||||
|
{
|
||||||
|
private boolean mValue;
|
||||||
|
|
||||||
|
public BooleanSetting(String key, String section, boolean value)
|
||||||
|
{
|
||||||
|
super(key, section);
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getValue()
|
||||||
|
{
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(boolean value)
|
||||||
|
{
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString()
|
||||||
|
{
|
||||||
|
return mValue ? "True" : "False";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings;
|
||||||
|
|
||||||
|
public final class FloatSetting extends Setting
|
||||||
|
{
|
||||||
|
private float mValue;
|
||||||
|
|
||||||
|
public FloatSetting(String key, String section, float value)
|
||||||
|
{
|
||||||
|
super(key, section);
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getValue()
|
||||||
|
{
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(float value)
|
||||||
|
{
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString()
|
||||||
|
{
|
||||||
|
return Float.toString(mValue);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings;
|
||||||
|
|
||||||
|
public final class IntSetting extends Setting
|
||||||
|
{
|
||||||
|
private int mValue;
|
||||||
|
|
||||||
|
public IntSetting(String key, String section, int value)
|
||||||
|
{
|
||||||
|
super(key, section);
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValue()
|
||||||
|
{
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(int value)
|
||||||
|
{
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString()
|
||||||
|
{
|
||||||
|
return Integer.toString(mValue);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction for a setting item as read from / written to Dolphin's configuration ini files.
|
||||||
|
* These files generally consist of a key/value pair, though the type of value is ambiguous and
|
||||||
|
* must be inferred at read-time. The type of value determines which child of this class is used
|
||||||
|
* to represent the Setting.
|
||||||
|
*/
|
||||||
|
public abstract class Setting
|
||||||
|
{
|
||||||
|
private String mKey;
|
||||||
|
private String mSection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public Setting(String key, String section)
|
||||||
|
{
|
||||||
|
mKey = key;
|
||||||
|
mSection = section;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The identifier used to write this setting to the ini file.
|
||||||
|
*/
|
||||||
|
public String getKey()
|
||||||
|
{
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The name of the header under which this Setting should be written in the ini file.
|
||||||
|
*/
|
||||||
|
public String getSection()
|
||||||
|
{
|
||||||
|
return mSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return A representation of this Setting's backing value converted to a String (e.g. for serialization).
|
||||||
|
*/
|
||||||
|
public abstract String getValueAsString();
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A semantically-related group of Settings objects. These Settings are
|
||||||
|
* internally stored as a Hashmap.
|
||||||
|
*/
|
||||||
|
public final class SettingSection
|
||||||
|
{
|
||||||
|
private String mName;
|
||||||
|
|
||||||
|
private HashMap<String, Setting> mSettings = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new SettingSection with no Settings in it.
|
||||||
|
*
|
||||||
|
* @param name The header of this section; e.g. [Core] or [Enhancements] without the brackets.
|
||||||
|
*/
|
||||||
|
public SettingSection(String name)
|
||||||
|
{
|
||||||
|
mName = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return mName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
mSettings.put(key, setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
public Setting getSetting(String key)
|
||||||
|
{
|
||||||
|
return mSettings.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, Setting> getSettings()
|
||||||
|
{
|
||||||
|
return mSettings;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings;
|
||||||
|
|
||||||
|
public final class StringSetting extends Setting
|
||||||
|
{
|
||||||
|
private String mValue;
|
||||||
|
|
||||||
|
public StringSetting(String key, String section, String value)
|
||||||
|
{
|
||||||
|
super(key, section);
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue()
|
||||||
|
{
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(String value)
|
||||||
|
{
|
||||||
|
mValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getValueAsString()
|
||||||
|
{
|
||||||
|
return mValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings.view;
|
||||||
|
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
|
||||||
|
public final class CheckBoxSetting extends SettingsItem
|
||||||
|
{
|
||||||
|
private boolean mDefaultValue;
|
||||||
|
|
||||||
|
public CheckBoxSetting(String key, String section, int titleId, int descriptionId, boolean defaultValue, Setting setting)
|
||||||
|
{
|
||||||
|
super(key, section, setting, titleId, descriptionId);
|
||||||
|
mDefaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isChecked()
|
||||||
|
{
|
||||||
|
if (getSetting() == null)
|
||||||
|
{
|
||||||
|
return mDefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BooleanSetting setting = (BooleanSetting) getSetting();
|
||||||
|
return setting.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a value to the backing boolean. If that boolean was previously null,
|
||||||
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
|
*
|
||||||
|
* @param checked Pretty self explanatory.
|
||||||
|
* @return null if overwritten successfully; otherwise, a newly created BooleanSetting.
|
||||||
|
*/
|
||||||
|
public BooleanSetting setChecked(boolean checked)
|
||||||
|
{
|
||||||
|
if (getSetting() == null)
|
||||||
|
{
|
||||||
|
BooleanSetting setting = new BooleanSetting(getKey(), getSection(), checked);
|
||||||
|
setSetting(setting);
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BooleanSetting setting = (BooleanSetting) getSetting();
|
||||||
|
setting.setValue(checked);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getType()
|
||||||
|
{
|
||||||
|
return TYPE_CHECKBOX;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings.view;
|
||||||
|
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
|
||||||
|
public final class HeaderSetting extends SettingsItem
|
||||||
|
{
|
||||||
|
public HeaderSetting(String key, Setting setting, int titleId, int descriptionId)
|
||||||
|
{
|
||||||
|
super(key, null, setting, titleId, descriptionId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getType()
|
||||||
|
{
|
||||||
|
return SettingsItem.TYPE_HEADER;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings.view;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
|
||||||
|
* Each one corresponds to a {@link Setting} object, so this class's subclasses
|
||||||
|
* should vaguely correspond to those subclasses. There are a few with multiple analogues
|
||||||
|
* and a few with none (Headers, for example, do not correspond to anything in the ini
|
||||||
|
* file.)
|
||||||
|
*/
|
||||||
|
public abstract class SettingsItem
|
||||||
|
{
|
||||||
|
public static final int TYPE_HEADER = 0;
|
||||||
|
public static final int TYPE_CHECKBOX = 1;
|
||||||
|
public static final int TYPE_SINGLE_CHOICE = 2;
|
||||||
|
public static final int TYPE_SLIDER = 3;
|
||||||
|
public static final int TYPE_SUBMENU = 4;
|
||||||
|
|
||||||
|
private String mKey;
|
||||||
|
private String mSection;
|
||||||
|
|
||||||
|
private Setting mSetting;
|
||||||
|
|
||||||
|
private int mNameId;
|
||||||
|
private int mDescriptionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base constructor. Takes a key / section name in case the third parameter, the Setting,
|
||||||
|
* is null; in which case, one can be constructed and saved using the key / section.
|
||||||
|
*
|
||||||
|
* @param key Identifier for the Setting represented by this Item.
|
||||||
|
* @param section Section to which the Setting belongs.
|
||||||
|
* @param setting A possibly-null backing Setting, to be modified on UI events.
|
||||||
|
* @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)
|
||||||
|
{
|
||||||
|
mKey = key;
|
||||||
|
mSection = section;
|
||||||
|
mSetting = setting;
|
||||||
|
mNameId = nameId;
|
||||||
|
mDescriptionId = descriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The identifier for the backing Setting.
|
||||||
|
*/
|
||||||
|
public String getKey()
|
||||||
|
{
|
||||||
|
return mKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The header under which the backing Setting belongs.
|
||||||
|
*/
|
||||||
|
public String getSection()
|
||||||
|
{
|
||||||
|
return mSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return The backing Setting, possibly null.
|
||||||
|
*/
|
||||||
|
public Setting getSetting()
|
||||||
|
{
|
||||||
|
return mSetting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the backing setting with a new one. Generally used in cases where
|
||||||
|
* the backing setting is null.
|
||||||
|
*
|
||||||
|
* @param setting A non-null Setting.
|
||||||
|
*/
|
||||||
|
public void setSetting(Setting setting)
|
||||||
|
{
|
||||||
|
mSetting = setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return A resource ID for a text string representing this Setting's name.
|
||||||
|
*/
|
||||||
|
public int getNameId()
|
||||||
|
{
|
||||||
|
return mNameId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDescriptionId()
|
||||||
|
{
|
||||||
|
return mDescriptionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used by {@link org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter}'s onCreateViewHolder()
|
||||||
|
* method to determine which type of ViewHolder should be created.
|
||||||
|
*
|
||||||
|
* @return An integer (ideally, one of the constants defined in this file)
|
||||||
|
*/
|
||||||
|
public abstract int getType();
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings.view;
|
||||||
|
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.IntSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
|
||||||
|
public final class SingleChoiceSetting extends SettingsItem
|
||||||
|
{
|
||||||
|
private int mDefaultValue;
|
||||||
|
|
||||||
|
private int mChoicesId;
|
||||||
|
private int mValuesId;
|
||||||
|
|
||||||
|
public SingleChoiceSetting(String key, String section, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting)
|
||||||
|
{
|
||||||
|
super(key, section, setting, titleId, descriptionId);
|
||||||
|
mValuesId = valuesId;
|
||||||
|
mChoicesId = choicesId;
|
||||||
|
mDefaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getChoicesId()
|
||||||
|
{
|
||||||
|
return mChoicesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getValuesId()
|
||||||
|
{
|
||||||
|
return mValuesId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedValue()
|
||||||
|
{
|
||||||
|
if (getSetting() != null)
|
||||||
|
{
|
||||||
|
IntSetting setting = (IntSetting) getSetting();
|
||||||
|
return setting.getValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return mDefaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a value to the backing int. If that int was previously null,
|
||||||
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
|
*
|
||||||
|
* @param selection New value of the int.
|
||||||
|
* @return null if overwritten successfully otherwise; a newly created IntSetting.
|
||||||
|
*/
|
||||||
|
public IntSetting setSelectedValue(int selection)
|
||||||
|
{
|
||||||
|
if (getSetting() == null)
|
||||||
|
{
|
||||||
|
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
|
||||||
|
setSetting(setting);
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntSetting setting = (IntSetting) getSetting();
|
||||||
|
setting.setValue(selection);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getType()
|
||||||
|
{
|
||||||
|
return TYPE_SINGLE_CHOICE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,118 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings.view;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.FloatSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.IntSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.Log;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||||
|
|
||||||
|
public final class SliderSetting extends SettingsItem
|
||||||
|
{
|
||||||
|
private int mMax;
|
||||||
|
private int mDefaultValue;
|
||||||
|
|
||||||
|
private String mUnits;
|
||||||
|
|
||||||
|
public SliderSetting(String key, String section, int titleId, int descriptionId, int max, String units, int defaultValue, Setting setting)
|
||||||
|
{
|
||||||
|
super(key, section, setting, titleId, descriptionId);
|
||||||
|
mMax = max;
|
||||||
|
mUnits = units;
|
||||||
|
mDefaultValue = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMax()
|
||||||
|
{
|
||||||
|
return mMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedValue()
|
||||||
|
{
|
||||||
|
Setting setting = getSetting();
|
||||||
|
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
return mDefaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting instanceof IntSetting)
|
||||||
|
{
|
||||||
|
IntSetting intSetting = (IntSetting) setting;
|
||||||
|
return intSetting.getValue();
|
||||||
|
}
|
||||||
|
else if (setting instanceof FloatSetting)
|
||||||
|
{
|
||||||
|
FloatSetting floatSetting = (FloatSetting) setting;
|
||||||
|
if (floatSetting.getKey().equals(SettingsFile.KEY_OVERCLOCK_PERCENT))
|
||||||
|
{
|
||||||
|
return Math.round(floatSetting.getValue() * 100);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Math.round(floatSetting.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.error("[SliderSetting] Error casting setting type.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a value to the backing int. If that int was previously null,
|
||||||
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
|
*
|
||||||
|
* @param selection New value of the int.
|
||||||
|
* @return null if overwritten successfully otherwise; a newly created IntSetting.
|
||||||
|
*/
|
||||||
|
public IntSetting setSelectedValue(int selection)
|
||||||
|
{
|
||||||
|
if (getSetting() == null)
|
||||||
|
{
|
||||||
|
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
|
||||||
|
setSetting(setting);
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntSetting setting = (IntSetting) getSetting();
|
||||||
|
setting.setValue(selection);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a value to the backing float. If that float was previously null,
|
||||||
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
|
*
|
||||||
|
* @param selection New value of the float.
|
||||||
|
* @return null if overwritten successfully otherwise; a newly created FloatSetting.
|
||||||
|
*/
|
||||||
|
public FloatSetting setSelectedValue(float selection)
|
||||||
|
{
|
||||||
|
if (getSetting() == null)
|
||||||
|
{
|
||||||
|
FloatSetting setting = new FloatSetting(getKey(), getSection(), selection);
|
||||||
|
setSetting(setting);
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FloatSetting setting = (FloatSetting) getSetting();
|
||||||
|
setting.setValue(selection);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUnits()
|
||||||
|
{
|
||||||
|
return mUnits;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getType()
|
||||||
|
{
|
||||||
|
return TYPE_SLIDER;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.model.settings.view;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
|
||||||
|
public final class SubmenuSetting extends SettingsItem
|
||||||
|
{
|
||||||
|
private String mMenuKey;
|
||||||
|
|
||||||
|
public SubmenuSetting(String key, Setting setting, int titleId, int descriptionId, String menuKey)
|
||||||
|
{
|
||||||
|
super(key, null, setting, titleId, descriptionId);
|
||||||
|
mMenuKey = menuKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMenuKey()
|
||||||
|
{
|
||||||
|
return mMenuKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getType()
|
||||||
|
{
|
||||||
|
return TYPE_SUBMENU;
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,6 @@ import android.preference.PreferenceManager;
|
|||||||
|
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.utils.Log;
|
import org.dolphinemu.dolphinemu.utils.Log;
|
||||||
import org.dolphinemu.dolphinemu.utils.UserPreferences;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
@ -61,10 +60,6 @@ public final class AssetCopyService extends IntentService
|
|||||||
copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini");
|
copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini");
|
||||||
copyAsset("WiimoteNew.ini", ConfigDir + File.separator + "WiimoteNew.ini");
|
copyAsset("WiimoteNew.ini", ConfigDir + File.separator + "WiimoteNew.ini");
|
||||||
|
|
||||||
// Load the configuration keys set in the Dolphin ini and gfx ini files
|
|
||||||
// into the application's shared preferences.
|
|
||||||
UserPreferences.LoadIniToPrefs(this);
|
|
||||||
|
|
||||||
// Record the fact that we've done this before, so we don't do it on every launch.
|
// Record the fact that we've done this before, so we don't do it on every launch.
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
SharedPreferences.Editor editor = preferences.edit();
|
SharedPreferences.Editor editor = preferences.edit();
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
package org.dolphinemu.dolphinemu.services;
|
|
||||||
|
|
||||||
import android.app.IntentService;
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.utils.Log;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.UserPreferences;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* IntentServices, unlike regular services, inherently run on a background thread.
|
|
||||||
* This IntentService saves all the options the user set in the Java-based UI into
|
|
||||||
* INI files the native code can read.
|
|
||||||
*/
|
|
||||||
public final class SettingsSaveService extends IntentService
|
|
||||||
{
|
|
||||||
public SettingsSaveService()
|
|
||||||
{
|
|
||||||
super("SettingsSaveService");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onHandleIntent(Intent intent)
|
|
||||||
{
|
|
||||||
Log.verbose("[SettingsSaveService] Saving settings to INI files...");
|
|
||||||
UserPreferences.SavePrefsToIni(this);
|
|
||||||
Log.verbose("[SettingsSaveService] Save successful.");
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,157 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation from:
|
||||||
|
* https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36
|
||||||
|
*/
|
||||||
|
public final class DividerItemDecoration extends RecyclerView.ItemDecoration
|
||||||
|
{
|
||||||
|
|
||||||
|
private Drawable mDivider;
|
||||||
|
private boolean mShowFirstDivider = false;
|
||||||
|
private boolean mShowLastDivider = false;
|
||||||
|
|
||||||
|
|
||||||
|
public DividerItemDecoration(Context context, AttributeSet attrs)
|
||||||
|
{
|
||||||
|
final TypedArray a = context
|
||||||
|
.obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
|
||||||
|
mDivider = a.getDrawable(0);
|
||||||
|
a.recycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
|
||||||
|
boolean showLastDivider)
|
||||||
|
{
|
||||||
|
this(context, attrs);
|
||||||
|
mShowFirstDivider = showFirstDivider;
|
||||||
|
mShowLastDivider = showLastDivider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DividerItemDecoration(Drawable divider)
|
||||||
|
{
|
||||||
|
mDivider = divider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
|
||||||
|
boolean showLastDivider)
|
||||||
|
{
|
||||||
|
this(divider);
|
||||||
|
mShowFirstDivider = showFirstDivider;
|
||||||
|
mShowLastDivider = showLastDivider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
|
||||||
|
RecyclerView.State state)
|
||||||
|
{
|
||||||
|
super.getItemOffsets(outRect, view, parent, state);
|
||||||
|
if (mDivider == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (parent.getChildPosition(view) < 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
|
||||||
|
{
|
||||||
|
outRect.top = mDivider.getIntrinsicHeight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outRect.left = mDivider.getIntrinsicWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state)
|
||||||
|
{
|
||||||
|
if (mDivider == null)
|
||||||
|
{
|
||||||
|
super.onDrawOver(c, parent, state);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialization needed to avoid compiler warning
|
||||||
|
int left = 0, right = 0, top = 0, bottom = 0, size;
|
||||||
|
int orientation = getOrientation(parent);
|
||||||
|
int childCount = parent.getChildCount();
|
||||||
|
|
||||||
|
if (orientation == LinearLayoutManager.VERTICAL)
|
||||||
|
{
|
||||||
|
size = mDivider.getIntrinsicHeight();
|
||||||
|
left = parent.getPaddingLeft();
|
||||||
|
right = parent.getWidth() - parent.getPaddingRight();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //horizontal
|
||||||
|
size = mDivider.getIntrinsicWidth();
|
||||||
|
top = parent.getPaddingTop();
|
||||||
|
bottom = parent.getHeight() - parent.getPaddingBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++)
|
||||||
|
{
|
||||||
|
View child = parent.getChildAt(i);
|
||||||
|
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||||
|
|
||||||
|
if (orientation == LinearLayoutManager.VERTICAL)
|
||||||
|
{
|
||||||
|
top = child.getTop() - params.topMargin;
|
||||||
|
bottom = top + size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //horizontal
|
||||||
|
left = child.getLeft() - params.leftMargin;
|
||||||
|
right = left + size;
|
||||||
|
}
|
||||||
|
mDivider.setBounds(left, top, right, bottom);
|
||||||
|
mDivider.draw(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
// show last divider
|
||||||
|
if (mShowLastDivider && childCount > 0)
|
||||||
|
{
|
||||||
|
View child = parent.getChildAt(childCount - 1);
|
||||||
|
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||||
|
if (orientation == LinearLayoutManager.VERTICAL)
|
||||||
|
{
|
||||||
|
top = child.getBottom() + params.bottomMargin;
|
||||||
|
bottom = top + size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // horizontal
|
||||||
|
left = child.getRight() + params.rightMargin;
|
||||||
|
right = left + size;
|
||||||
|
}
|
||||||
|
mDivider.setBounds(left, top, right, bottom);
|
||||||
|
mDivider.draw(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getOrientation(RecyclerView parent)
|
||||||
|
{
|
||||||
|
if (parent.getLayoutManager() instanceof LinearLayoutManager)
|
||||||
|
{
|
||||||
|
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
|
||||||
|
return layoutManager.getOrientation();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"DividerItemDecoration can only be used with a LinearLayoutManager.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -16,10 +16,10 @@ import android.view.View;
|
|||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
|
import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
|
||||||
import org.dolphinemu.dolphinemu.activities.SettingsActivity;
|
|
||||||
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
|
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
|
||||||
import org.dolphinemu.dolphinemu.model.GameProvider;
|
import org.dolphinemu.dolphinemu.model.GameProvider;
|
||||||
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView;
|
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsActivity;
|
||||||
import org.dolphinemu.dolphinemu.utils.StartupHandler;
|
import org.dolphinemu.dolphinemu.utils.StartupHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,9 +115,9 @@ public final class MainActivity extends AppCompatActivity implements MainView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launchSettingsActivity()
|
public void launchSettingsActivity(String menuTag)
|
||||||
{
|
{
|
||||||
SettingsActivity.launch(this);
|
SettingsActivity.launch(this, menuTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -7,6 +7,7 @@ import org.dolphinemu.dolphinemu.DolphinApplication;
|
|||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.model.GameDatabase;
|
import org.dolphinemu.dolphinemu.model.GameDatabase;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||||
|
|
||||||
import rx.android.schedulers.AndroidSchedulers;
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
import rx.functions.Action1;
|
import rx.functions.Action1;
|
||||||
@ -41,8 +42,12 @@ public final class MainPresenter
|
|||||||
{
|
{
|
||||||
switch (itemId)
|
switch (itemId)
|
||||||
{
|
{
|
||||||
case R.id.menu_settings:
|
case R.id.menu_settings_core:
|
||||||
mView.launchSettingsActivity();
|
mView.launchSettingsActivity(SettingsFile.FILE_NAME_DOLPHIN);
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case R.id.menu_settings_video:
|
||||||
|
mView.launchSettingsActivity(SettingsFile.FILE_NAME_GFX);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.menu_refresh:
|
case R.id.menu_refresh:
|
||||||
|
@ -32,7 +32,7 @@ public interface MainView
|
|||||||
void refreshFragmentScreenshot(int fragmentPosition);
|
void refreshFragmentScreenshot(int fragmentPosition);
|
||||||
|
|
||||||
|
|
||||||
void launchSettingsActivity();
|
void launchSettingsActivity(String menuTag);
|
||||||
|
|
||||||
void launchFileListActivity();
|
void launchFileListActivity();
|
||||||
|
|
||||||
|
@ -20,11 +20,12 @@ import android.support.v17.leanback.widget.RowPresenter;
|
|||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
|
import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
|
||||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
|
||||||
import org.dolphinemu.dolphinemu.activities.SettingsActivity;
|
|
||||||
import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
|
import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
|
||||||
import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
|
import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
|
||||||
import org.dolphinemu.dolphinemu.model.Game;
|
import org.dolphinemu.dolphinemu.model.Game;
|
||||||
import org.dolphinemu.dolphinemu.model.TvSettingsItem;
|
import org.dolphinemu.dolphinemu.model.TvSettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsActivity;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||||
import org.dolphinemu.dolphinemu.utils.StartupHandler;
|
import org.dolphinemu.dolphinemu.utils.StartupHandler;
|
||||||
import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
|
import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
|
||||||
|
|
||||||
@ -112,9 +113,9 @@ public final class TvMainActivity extends Activity implements MainView
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void launchSettingsActivity()
|
public void launchSettingsActivity(String menuTag)
|
||||||
{
|
{
|
||||||
SettingsActivity.launch(this);
|
SettingsActivity.launch(this, SettingsFile.FILE_NAME_DOLPHIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -229,9 +230,13 @@ public final class TvMainActivity extends Activity implements MainView
|
|||||||
R.drawable.ic_refresh_tv,
|
R.drawable.ic_refresh_tv,
|
||||||
R.string.grid_menu_refresh));
|
R.string.grid_menu_refresh));
|
||||||
|
|
||||||
rowItems.add(new TvSettingsItem(R.id.menu_settings,
|
rowItems.add(new TvSettingsItem(R.id.menu_settings_core,
|
||||||
R.drawable.ic_settings_tv,
|
R.drawable.ic_settings_core_tv,
|
||||||
R.string.grid_menu_settings));
|
R.string.grid_menu_core_settings));
|
||||||
|
|
||||||
|
rowItems.add(new TvSettingsItem(R.id.menu_settings_video,
|
||||||
|
R.drawable.ic_settings_graphics_tv,
|
||||||
|
R.string.grid_menu_core_settings));
|
||||||
|
|
||||||
rowItems.add(new TvSettingsItem(R.id.button_add_directory,
|
rowItems.add(new TvSettingsItem(R.id.button_add_directory,
|
||||||
R.drawable.ic_add_tv,
|
R.drawable.ic_add_tv,
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.v4.app.FragmentTransaction;
|
||||||
|
import android.support.v7.app.AppCompatActivity;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.BuildConfig;
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
|
||||||
|
{
|
||||||
|
private SettingsActivityPresenter mPresenter = new SettingsActivityPresenter(this);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_settings);
|
||||||
|
|
||||||
|
Intent launcher = getIntent();
|
||||||
|
String filename = launcher.getStringExtra(ARGUMENT_FILE_NAME);
|
||||||
|
|
||||||
|
mPresenter.onCreate(savedInstanceState, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is called, the user has left the settings screen (potentially through the
|
||||||
|
* home button) and will expect their changes to be persisted. So we kick off an
|
||||||
|
* IntentService which will do so on a background thread.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void onStop()
|
||||||
|
{
|
||||||
|
super.onStop();
|
||||||
|
|
||||||
|
mPresenter.onStop(isFinishing());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showSettingsFragment(String menuTag, boolean addToStack)
|
||||||
|
{
|
||||||
|
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.frame_content, SettingsFragment.newInstance(menuTag), SettingsFragment.FRAGMENT_TAG);
|
||||||
|
|
||||||
|
if (addToStack)
|
||||||
|
{
|
||||||
|
transaction.addToBackStack(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HashMap<String, SettingSection> getSettings()
|
||||||
|
{
|
||||||
|
return mPresenter.getSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setSettings(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
mPresenter.setSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSettingsFileLoaded(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
SettingsFragmentView fragment = getFragment();
|
||||||
|
|
||||||
|
if (fragment != null)
|
||||||
|
{
|
||||||
|
fragment.onSettingsFileLoaded(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showToastMessage(String message)
|
||||||
|
{
|
||||||
|
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private SettingsFragment getFragment()
|
||||||
|
{
|
||||||
|
return (SettingsFragment) getSupportFragmentManager().findFragmentByTag(SettingsFragment.FRAGMENT_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String ARGUMENT_FILE_NAME = BuildConfig.APPLICATION_ID + ".file_name";
|
||||||
|
|
||||||
|
public static void launch(Context context, String menuTag)
|
||||||
|
{
|
||||||
|
Intent settings = new Intent(context, SettingsActivity.class);
|
||||||
|
|
||||||
|
settings.putExtra(ARGUMENT_FILE_NAME, menuTag);
|
||||||
|
|
||||||
|
context.startActivity(settings);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.Log;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import rx.android.schedulers.AndroidSchedulers;
|
||||||
|
import rx.functions.Action1;
|
||||||
|
import rx.schedulers.Schedulers;
|
||||||
|
|
||||||
|
public final class SettingsActivityPresenter
|
||||||
|
{
|
||||||
|
private SettingsActivityView mView;
|
||||||
|
|
||||||
|
private String mFileName;
|
||||||
|
private HashMap<String, SettingSection> mSettingsBySection;
|
||||||
|
|
||||||
|
public SettingsActivityPresenter(SettingsActivityView view)
|
||||||
|
{
|
||||||
|
mView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCreate(Bundle savedInstanceState, final String filename)
|
||||||
|
{
|
||||||
|
mFileName = filename;
|
||||||
|
|
||||||
|
if (savedInstanceState == null)
|
||||||
|
{
|
||||||
|
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.onSettingsFileLoaded(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mView.showSettingsFragment(mFileName, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSettings(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
mSettingsBySection = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, SettingSection> getSettings()
|
||||||
|
{
|
||||||
|
return mSettingsBySection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onStop(boolean finishing)
|
||||||
|
{
|
||||||
|
if (mSettingsBySection != null && finishing)
|
||||||
|
{
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction for the Activity that manages SettingsFragments.
|
||||||
|
*/
|
||||||
|
public interface SettingsActivityView
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Show a new SettingsFragment.
|
||||||
|
*
|
||||||
|
* @param menuTag Identifier for the settings group that should be displayed.
|
||||||
|
* @param addToStack Whether or not this fragment should replace a previous one.
|
||||||
|
*/
|
||||||
|
void showSettingsFragment(String menuTag, boolean addToStack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
HashMap<String, SettingSection> getSettings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to provide the Activity with a Settings Hashmap 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.
|
||||||
|
*
|
||||||
|
* @param settings The Fragment's Settings hashmap.
|
||||||
|
*/
|
||||||
|
void setSettings(HashMap<String, SettingSection> settings);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an asynchronous load operation completes.
|
||||||
|
*
|
||||||
|
* @param settings The (possibly null) result of the load operation.
|
||||||
|
*/
|
||||||
|
void onSettingsFileLoaded(HashMap<String, SettingSection> settings);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display a popup text message on screen.
|
||||||
|
*
|
||||||
|
* @param message The contents of the onscreen message.
|
||||||
|
*/
|
||||||
|
void showToastMessage(String message);
|
||||||
|
}
|
@ -0,0 +1,334 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.FloatSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.IntSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.CheckBoxSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.viewholder.CheckBoxSettingViewHolder;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.viewholder.HeaderViewHolder;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.viewholder.SettingViewHolder;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.viewholder.SingleChoiceViewHolder;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.viewholder.SliderViewHolder;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.viewholder.SubmenuViewHolder;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.Log;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolder>
|
||||||
|
implements DialogInterface.OnClickListener, SeekBar.OnSeekBarChangeListener
|
||||||
|
{
|
||||||
|
private SettingsFragmentView mView;
|
||||||
|
private Context mContext;
|
||||||
|
private ArrayList<SettingsItem> mSettings;
|
||||||
|
|
||||||
|
private SettingsItem mClickedItem;
|
||||||
|
private int mSeekbarProgress;
|
||||||
|
|
||||||
|
private AlertDialog mDialog;
|
||||||
|
private TextView mTextSliderValue;
|
||||||
|
|
||||||
|
public SettingsAdapter(SettingsFragmentView view, Context context)
|
||||||
|
{
|
||||||
|
mView = view;
|
||||||
|
mContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SettingViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
|
||||||
|
{
|
||||||
|
View view;
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||||
|
|
||||||
|
switch (viewType)
|
||||||
|
{
|
||||||
|
case SettingsItem.TYPE_HEADER:
|
||||||
|
view = inflater.inflate(R.layout.list_item_settings_header, parent, false);
|
||||||
|
return new HeaderViewHolder(view, this);
|
||||||
|
|
||||||
|
case SettingsItem.TYPE_CHECKBOX:
|
||||||
|
view = inflater.inflate(R.layout.list_item_setting_checkbox, parent, false);
|
||||||
|
return new CheckBoxSettingViewHolder(view, this);
|
||||||
|
|
||||||
|
case SettingsItem.TYPE_SINGLE_CHOICE:
|
||||||
|
view = inflater.inflate(R.layout.list_item_setting, parent, false);
|
||||||
|
return new SingleChoiceViewHolder(view, this);
|
||||||
|
|
||||||
|
case SettingsItem.TYPE_SLIDER:
|
||||||
|
view = inflater.inflate(R.layout.list_item_setting, parent, false);
|
||||||
|
return new SliderViewHolder(view, this);
|
||||||
|
|
||||||
|
case SettingsItem.TYPE_SUBMENU:
|
||||||
|
view = inflater.inflate(R.layout.list_item_setting, parent, false);
|
||||||
|
return new SubmenuViewHolder(view, this);
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.error("[SettingsAdapter] Invalid view type: " + viewType);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(SettingViewHolder holder, int position)
|
||||||
|
{
|
||||||
|
holder.bind(getItem(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SettingsItem getItem(int position)
|
||||||
|
{
|
||||||
|
return mSettings.get(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount()
|
||||||
|
{
|
||||||
|
if (mSettings != null)
|
||||||
|
{
|
||||||
|
return mSettings.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position)
|
||||||
|
{
|
||||||
|
return getItem(position).getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSettings(ArrayList<SettingsItem> settings)
|
||||||
|
{
|
||||||
|
mSettings = settings;
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBooleanClick(CheckBoxSetting item, int position, boolean checked)
|
||||||
|
{
|
||||||
|
BooleanSetting setting = item.setChecked(checked);
|
||||||
|
notifyItemChanged(position);
|
||||||
|
|
||||||
|
if (setting != null)
|
||||||
|
{
|
||||||
|
mView.putSetting(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSingleChoiceClick(SingleChoiceSetting item)
|
||||||
|
{
|
||||||
|
mClickedItem = item;
|
||||||
|
|
||||||
|
int value = getSelectionForSingleChoiceValue(item);
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(mView.getActivity());
|
||||||
|
|
||||||
|
builder.setTitle(item.getNameId());
|
||||||
|
builder.setSingleChoiceItems(item.getChoicesId(), value, this);
|
||||||
|
|
||||||
|
mDialog = builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSliderClick(SliderSetting item)
|
||||||
|
{
|
||||||
|
mClickedItem = item;
|
||||||
|
mSeekbarProgress = item.getSelectedValue();
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(mView.getActivity());
|
||||||
|
|
||||||
|
LayoutInflater inflater = LayoutInflater.from(mView.getActivity());
|
||||||
|
View view = inflater.inflate(R.layout.dialog_seekbar, null);
|
||||||
|
|
||||||
|
builder.setTitle(item.getNameId());
|
||||||
|
builder.setView(view);
|
||||||
|
builder.setPositiveButton(R.string.dialog_seekbar_pos, this);
|
||||||
|
builder.setNegativeButton(R.string.dialog_seekbar_neg, this);
|
||||||
|
mDialog = builder.show();
|
||||||
|
|
||||||
|
mTextSliderValue = (TextView) view.findViewById(R.id.text_value);
|
||||||
|
mTextSliderValue.setText(String.valueOf(mSeekbarProgress));
|
||||||
|
|
||||||
|
TextView units = (TextView) view.findViewById(R.id.text_units);
|
||||||
|
units.setText(item.getUnits());
|
||||||
|
|
||||||
|
SeekBar seekbar = (SeekBar) view.findViewById(R.id.seekbar);
|
||||||
|
|
||||||
|
seekbar.setMax(item.getMax());
|
||||||
|
seekbar.setProgress(mSeekbarProgress);
|
||||||
|
|
||||||
|
seekbar.setOnSeekBarChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSubmenuClick(SubmenuSetting item)
|
||||||
|
{
|
||||||
|
mView.loadSubMenu(item.getMenuKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
if (mClickedItem instanceof SingleChoiceSetting)
|
||||||
|
{
|
||||||
|
SingleChoiceSetting scSetting = (SingleChoiceSetting) mClickedItem;
|
||||||
|
|
||||||
|
int value = getValueForSingleChoiceSelection(scSetting, which);
|
||||||
|
|
||||||
|
// Get the backing Setting, which may be null (if for example it was missing from the file)
|
||||||
|
IntSetting setting = scSetting.setSelectedValue(value);
|
||||||
|
if (setting != null)
|
||||||
|
{
|
||||||
|
mView.putSetting(setting);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (scSetting.getKey().equals(SettingsFile.KEY_XFB_METHOD))
|
||||||
|
{
|
||||||
|
putXfbSetting(which);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closeDialog();
|
||||||
|
}
|
||||||
|
else if (mClickedItem instanceof SliderSetting)
|
||||||
|
{
|
||||||
|
SliderSetting sliderSetting = (SliderSetting) mClickedItem;
|
||||||
|
if (sliderSetting.getSetting() instanceof FloatSetting)
|
||||||
|
{
|
||||||
|
float value;
|
||||||
|
|
||||||
|
if (sliderSetting.getKey().equals(SettingsFile.KEY_OVERCLOCK_PERCENT))
|
||||||
|
{
|
||||||
|
value = mSeekbarProgress / 100.0f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = (float) mSeekbarProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatSetting setting = sliderSetting.setSelectedValue(value);
|
||||||
|
if (setting != null)
|
||||||
|
{
|
||||||
|
mView.putSetting(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IntSetting setting = sliderSetting.setSelectedValue(mSeekbarProgress);
|
||||||
|
if (setting != null)
|
||||||
|
{
|
||||||
|
mView.putSetting(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mClickedItem = null;
|
||||||
|
mSeekbarProgress = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeDialog()
|
||||||
|
{
|
||||||
|
if (mDialog != null)
|
||||||
|
{
|
||||||
|
mDialog.dismiss();
|
||||||
|
mDialog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
|
||||||
|
{
|
||||||
|
mSeekbarProgress = progress;
|
||||||
|
mTextSliderValue.setText(String.valueOf(mSeekbarProgress));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getValueForSingleChoiceSelection(SingleChoiceSetting item, int which)
|
||||||
|
{
|
||||||
|
int valuesId = item.getValuesId();
|
||||||
|
|
||||||
|
if (valuesId > 0)
|
||||||
|
{
|
||||||
|
int[] valuesArray = mContext.getResources().getIntArray(valuesId);
|
||||||
|
return valuesArray[which];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return which;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSelectionForSingleChoiceValue(SingleChoiceSetting item)
|
||||||
|
{
|
||||||
|
int value = item.getSelectedValue();
|
||||||
|
int valuesId = item.getValuesId();
|
||||||
|
|
||||||
|
if (valuesId > 0)
|
||||||
|
{
|
||||||
|
int[] valuesArray = mContext.getResources().getIntArray(valuesId);
|
||||||
|
for (int index = 0; index < valuesArray.length; index++)
|
||||||
|
{
|
||||||
|
int current = valuesArray[index];
|
||||||
|
if (current == value)
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putXfbSetting(int which)
|
||||||
|
{
|
||||||
|
BooleanSetting xfbEnable = null;
|
||||||
|
BooleanSetting xfbReal = null;
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mView.putSetting(xfbEnable);
|
||||||
|
mView.putSetting(xfbReal);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,141 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.BuildConfig;
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
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 java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public final class SettingsFragment extends Fragment implements SettingsFragmentView
|
||||||
|
{
|
||||||
|
private SettingsFragmentPresenter mPresenter = new SettingsFragmentPresenter(this);
|
||||||
|
private SettingsActivityView mActivity;
|
||||||
|
|
||||||
|
private SettingsAdapter mAdapter;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context)
|
||||||
|
{
|
||||||
|
super.onAttach(context);
|
||||||
|
|
||||||
|
mActivity = (SettingsActivityView) context;
|
||||||
|
mPresenter.onAttach();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setRetainInstance(true);
|
||||||
|
String menuTag = getArguments().getString(ARGUMENT_MENU_TAG);
|
||||||
|
|
||||||
|
mAdapter = new SettingsAdapter(this, getActivity());
|
||||||
|
|
||||||
|
mPresenter.onCreate(menuTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
return inflater.inflate(R.layout.fragment_settings, container, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(View view, @Nullable Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
LinearLayoutManager manager = new LinearLayoutManager(getActivity());
|
||||||
|
|
||||||
|
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list_settings);
|
||||||
|
|
||||||
|
recyclerView.setAdapter(mAdapter);
|
||||||
|
recyclerView.setLayoutManager(manager);
|
||||||
|
recyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), null));
|
||||||
|
|
||||||
|
SettingsActivityView activity = (SettingsActivityView) getActivity();
|
||||||
|
HashMap<String, SettingSection> settings = activity.getSettings();
|
||||||
|
|
||||||
|
mPresenter.onViewCreated(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach()
|
||||||
|
{
|
||||||
|
super.onDetach();
|
||||||
|
mActivity = null;
|
||||||
|
|
||||||
|
if (mAdapter != null)
|
||||||
|
{
|
||||||
|
mAdapter.closeDialog();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSettingsFileLoaded(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
mPresenter.setSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void passSettingsToActivity(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
if (mActivity != null)
|
||||||
|
{
|
||||||
|
mActivity.setSettings(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showSettingsList(ArrayList<SettingsItem> settingsList)
|
||||||
|
{
|
||||||
|
mAdapter.setSettings(settingsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadSubMenu(String menuKey)
|
||||||
|
{
|
||||||
|
mActivity.showSettingsFragment(menuKey, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void showToastMessage(String message)
|
||||||
|
{
|
||||||
|
mActivity.showToastMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putSetting(Setting setting)
|
||||||
|
{
|
||||||
|
mPresenter.putSetting(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".fragment.settings";
|
||||||
|
|
||||||
|
public static final String ARGUMENT_MENU_TAG = FRAGMENT_TAG + ".menu_tag";
|
||||||
|
|
||||||
|
public static Fragment newInstance(String menuTag)
|
||||||
|
{
|
||||||
|
SettingsFragment fragment = new SettingsFragment();
|
||||||
|
|
||||||
|
Bundle arguments = new Bundle();
|
||||||
|
arguments.putString(ARGUMENT_MENU_TAG, menuTag);
|
||||||
|
|
||||||
|
fragment.setArguments(arguments);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,257 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
|
||||||
|
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.view.CheckBoxSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.HeaderSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.EGLHelper;
|
||||||
|
import org.dolphinemu.dolphinemu.utils.SettingsFile;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public final class SettingsFragmentPresenter
|
||||||
|
{
|
||||||
|
private SettingsFragmentView mView;
|
||||||
|
|
||||||
|
private String mMenuTag;
|
||||||
|
|
||||||
|
private HashMap<String, SettingSection> mSettings;
|
||||||
|
private ArrayList<SettingsItem> mSettingsList;
|
||||||
|
|
||||||
|
public SettingsFragmentPresenter(SettingsFragmentView view)
|
||||||
|
{
|
||||||
|
mView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCreate(String menuTag)
|
||||||
|
{
|
||||||
|
mMenuTag = menuTag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onViewCreated(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
setSettings(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the screen is rotated, the Activity will forget the settings map. This fragment
|
||||||
|
* won't, though; so rather than have the Activity reload from disk, have the fragment pass
|
||||||
|
* the settings map back to the Activity.
|
||||||
|
*/
|
||||||
|
public void onAttach()
|
||||||
|
{
|
||||||
|
if (mSettings != null)
|
||||||
|
{
|
||||||
|
mView.passSettingsToActivity(mSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putSetting(Setting setting)
|
||||||
|
{
|
||||||
|
mSettings.get(setting.getSection()).putSetting(setting.getKey(), setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSettings(HashMap<String, SettingSection> settings)
|
||||||
|
{
|
||||||
|
if (mSettingsList == null)
|
||||||
|
{
|
||||||
|
mSettings = settings;
|
||||||
|
|
||||||
|
loadSettingsList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mView.showSettingsList(mSettingsList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSettingsList()
|
||||||
|
{
|
||||||
|
ArrayList<SettingsItem> sl = new ArrayList<>();
|
||||||
|
|
||||||
|
switch (mMenuTag)
|
||||||
|
{
|
||||||
|
case SettingsFile.FILE_NAME_DOLPHIN:
|
||||||
|
addCoreSettings(sl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SettingsFile.FILE_NAME_GFX:
|
||||||
|
addGraphicsSettings(sl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SettingsFile.SECTION_GFX_ENHANCEMENTS:
|
||||||
|
addEnhanceSettings(sl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SettingsFile.SECTION_GFX_HACKS:
|
||||||
|
addHackSettings(sl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
mView.showToastMessage("Unimplemented menu.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSettingsList = sl;
|
||||||
|
mView.showSettingsList(mSettingsList);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addCoreSettings(ArrayList<SettingsItem> sl)
|
||||||
|
{
|
||||||
|
Setting cpuCore = null;
|
||||||
|
Setting dualCore = null;
|
||||||
|
Setting overclockEnable = null;
|
||||||
|
Setting overclock = null;
|
||||||
|
|
||||||
|
if (mSettings != null)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mSettings = new HashMap<>();
|
||||||
|
mSettings.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.string_emu_cores, R.array.int_emu_cores, 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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addGraphicsSettings(ArrayList<SettingsItem> sl)
|
||||||
|
{
|
||||||
|
Setting showFps = null;
|
||||||
|
|
||||||
|
if (mSettings != null)
|
||||||
|
{
|
||||||
|
showFps = mSettings.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));
|
||||||
|
|
||||||
|
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 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// Setting shader = mSettings.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));
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check if we support stereo
|
||||||
|
If we support desktop GL then we must support at least OpenGL 3.2
|
||||||
|
If we only support OpenGLES then we need both OpenGLES 3.1 and AEP
|
||||||
|
*/
|
||||||
|
EGLHelper helper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
|
||||||
|
|
||||||
|
if ((helper.supportsOpenGL() && helper.GetVersion() >= 320) ||
|
||||||
|
(helper.supportsGLES3() && helper.GetVersion() >= 310 && helper.SupportsExtension("GL_ANDROID_extension_pack_es31a")))
|
||||||
|
{
|
||||||
|
sl.add(new SubmenuSetting(null, null, R.string.stereoscopy, 0, SettingsFile.SECTION_STEREOSCOPY));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHackSettings(ArrayList<SettingsItem> sl)
|
||||||
|
{
|
||||||
|
int xfbValue = getXfbValue();
|
||||||
|
|
||||||
|
Setting skipEFB = mSettings.get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_SKIP_EFB);
|
||||||
|
Setting ignoreFormat = mSettings.get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_IGNORE_FORMAT);
|
||||||
|
Setting efbToTexture = mSettings.get(SettingsFile.SECTION_GFX_HACKS).getSetting(SettingsFile.KEY_EFB_TEXTURE);
|
||||||
|
Setting texCacheAccuracy = mSettings.get(SettingsFile.SECTION_GFX_HACKS).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_HACKS).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, false, 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 HeaderSetting(null, null, R.string.texture_cache, 0));
|
||||||
|
sl.add(new SingleChoiceSetting(SettingsFile.KEY_TEXCACHE_ACCURACY, SettingsFile.SECTION_GFX_HACKS, 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 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_HACKS, R.string.aspect_ratio, R.string.aspect_ratio_descrip, R.array.aspectRatioEntries, R.array.aspectRatioValues, 0, aspectRatio));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getXfbValue()
|
||||||
|
{
|
||||||
|
int xfbValue;
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
if (!usingXFB)
|
||||||
|
{
|
||||||
|
xfbValue = 0;
|
||||||
|
}
|
||||||
|
else if (!usingRealXFB)
|
||||||
|
{
|
||||||
|
xfbValue = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xfbValue = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullPointerException ex)
|
||||||
|
{
|
||||||
|
xfbValue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xfbValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.Setting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.SettingSection;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction for a screen showing a list of settings. Instances of
|
||||||
|
* this type of view will each display a layer of the setting hierarchy.
|
||||||
|
*/
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
void onSettingsFileLoaded(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
|
||||||
|
* do not require an additional load operation.
|
||||||
|
*
|
||||||
|
* @param settings A Hashmap containing all the settings
|
||||||
|
*/
|
||||||
|
void passSettingsToActivity(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
|
||||||
|
*/
|
||||||
|
void showSettingsList(ArrayList<SettingsItem> settingsList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The Fragment's containing activity.
|
||||||
|
*/
|
||||||
|
Activity getActivity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the Fragment to tell the containing Activity to show a new
|
||||||
|
* Fragment containing a submenu of settings.
|
||||||
|
*
|
||||||
|
* @param menuKey Identifier for the settings group that should be shown.
|
||||||
|
*/
|
||||||
|
void loadSubMenu(String menuKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the Fragment to tell the containing activity to display a toast message.
|
||||||
|
*
|
||||||
|
* @param message Text to be shown in the Toast
|
||||||
|
*/
|
||||||
|
void showToastMessage(String message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Have the fragment add a setting to the Hashmap.
|
||||||
|
*
|
||||||
|
* @param setting The (possibly previously missing) new setting.
|
||||||
|
*/
|
||||||
|
void putSetting(Setting setting);
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings.viewholder;
|
||||||
|
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.CheckBoxSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
|
||||||
|
|
||||||
|
public final class CheckBoxSettingViewHolder extends SettingViewHolder
|
||||||
|
{
|
||||||
|
private CheckBoxSetting mItem;
|
||||||
|
|
||||||
|
private TextView mTextSettingName;
|
||||||
|
private TextView mTextSettingDescription;
|
||||||
|
|
||||||
|
private CheckBox mCheckbox;
|
||||||
|
|
||||||
|
public CheckBoxSettingViewHolder(View itemView, SettingsAdapter adapter)
|
||||||
|
{
|
||||||
|
super(itemView, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void findViews(View root)
|
||||||
|
{
|
||||||
|
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
|
||||||
|
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
|
||||||
|
mCheckbox = (CheckBox) root.findViewById(R.id.checkbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(SettingsItem item)
|
||||||
|
{
|
||||||
|
mItem = (CheckBoxSetting) item;
|
||||||
|
|
||||||
|
mTextSettingName.setText(item.getNameId());
|
||||||
|
|
||||||
|
if (item.getDescriptionId() > 0)
|
||||||
|
{
|
||||||
|
mTextSettingDescription.setText(item.getDescriptionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
mCheckbox.setChecked(mItem.isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View clicked)
|
||||||
|
{
|
||||||
|
mCheckbox.toggle();
|
||||||
|
|
||||||
|
getAdapter().onBooleanClick(mItem, getAdapterPosition(), mCheckbox.isChecked());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings.viewholder;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
|
||||||
|
|
||||||
|
public final class HeaderViewHolder extends SettingViewHolder
|
||||||
|
{
|
||||||
|
private TextView mHeaderName;
|
||||||
|
|
||||||
|
public HeaderViewHolder(View itemView, SettingsAdapter adapter)
|
||||||
|
{
|
||||||
|
super(itemView, adapter);
|
||||||
|
itemView.setOnClickListener(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void findViews(View root)
|
||||||
|
{
|
||||||
|
mHeaderName = (TextView) root.findViewById(R.id.text_header_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(SettingsItem item)
|
||||||
|
{
|
||||||
|
mHeaderName.setText(item.getNameId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View clicked)
|
||||||
|
{
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings.viewholder;
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
|
||||||
|
|
||||||
|
public abstract class SettingViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
|
||||||
|
{
|
||||||
|
private SettingsAdapter mAdapter;
|
||||||
|
|
||||||
|
public SettingViewHolder(View itemView, SettingsAdapter adapter)
|
||||||
|
{
|
||||||
|
super(itemView);
|
||||||
|
|
||||||
|
mAdapter = adapter;
|
||||||
|
|
||||||
|
itemView.setOnClickListener(this);
|
||||||
|
|
||||||
|
findViews(itemView);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SettingsAdapter getAdapter()
|
||||||
|
{
|
||||||
|
return mAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets handles to all this ViewHolder's child views using their XML-defined identifiers.
|
||||||
|
*
|
||||||
|
* @param root The newly inflated top-level view.
|
||||||
|
*/
|
||||||
|
protected abstract void findViews(View root);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the adapter to set this ViewHolder's child views to display the list item
|
||||||
|
* it must now represent.
|
||||||
|
*
|
||||||
|
* @param item The list item that should be represented by this ViewHolder.
|
||||||
|
*/
|
||||||
|
public abstract void bind(SettingsItem item);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when this ViewHolder's view is clicked on. Implementations should usually pass
|
||||||
|
* this event up to the adapter.
|
||||||
|
*
|
||||||
|
* @param clicked The view that was clicked on.
|
||||||
|
*/
|
||||||
|
public abstract void onClick(View clicked);
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings.viewholder;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SingleChoiceSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
|
||||||
|
|
||||||
|
public final class SingleChoiceViewHolder extends SettingViewHolder
|
||||||
|
{
|
||||||
|
private SingleChoiceSetting mItem;
|
||||||
|
|
||||||
|
private TextView mTextSettingName;
|
||||||
|
private TextView mTextSettingDescription;
|
||||||
|
|
||||||
|
public SingleChoiceViewHolder(View itemView, SettingsAdapter adapter)
|
||||||
|
{
|
||||||
|
super(itemView, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void findViews(View root)
|
||||||
|
{
|
||||||
|
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
|
||||||
|
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(SettingsItem item)
|
||||||
|
{
|
||||||
|
mItem = (SingleChoiceSetting) item;
|
||||||
|
|
||||||
|
mTextSettingName.setText(item.getNameId());
|
||||||
|
|
||||||
|
if (item.getDescriptionId() > 0)
|
||||||
|
{
|
||||||
|
mTextSettingDescription.setText(item.getDescriptionId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View clicked)
|
||||||
|
{
|
||||||
|
getAdapter().onSingleChoiceClick(mItem);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings.viewholder;
|
||||||
|
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SliderSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
|
||||||
|
|
||||||
|
public final class SliderViewHolder extends SettingViewHolder
|
||||||
|
{
|
||||||
|
private SliderSetting mItem;
|
||||||
|
|
||||||
|
private TextView mTextSettingName;
|
||||||
|
private TextView mTextSettingDescription;
|
||||||
|
|
||||||
|
public SliderViewHolder(View itemView, SettingsAdapter adapter)
|
||||||
|
{
|
||||||
|
super(itemView, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void findViews(View root)
|
||||||
|
{
|
||||||
|
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
|
||||||
|
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(SettingsItem item)
|
||||||
|
{
|
||||||
|
mItem = (SliderSetting) item;
|
||||||
|
|
||||||
|
mTextSettingName.setText(item.getNameId());
|
||||||
|
|
||||||
|
if (item.getDescriptionId() > 0)
|
||||||
|
{
|
||||||
|
mTextSettingDescription.setText(item.getDescriptionId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View clicked)
|
||||||
|
{
|
||||||
|
getAdapter().onSliderClick(mItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.ui.settings.viewholder;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SettingsItem;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.view.SubmenuSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter;
|
||||||
|
|
||||||
|
public final class SubmenuViewHolder extends SettingViewHolder
|
||||||
|
{
|
||||||
|
private SubmenuSetting mItem;
|
||||||
|
|
||||||
|
private TextView mTextSettingName;
|
||||||
|
private TextView mTextSettingDescription;
|
||||||
|
|
||||||
|
public SubmenuViewHolder(View itemView, SettingsAdapter adapter)
|
||||||
|
{
|
||||||
|
super(itemView, adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void findViews(View root)
|
||||||
|
{
|
||||||
|
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
|
||||||
|
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(SettingsItem item)
|
||||||
|
{
|
||||||
|
mItem = (SubmenuSetting) item;
|
||||||
|
|
||||||
|
mTextSettingName.setText(item.getNameId());
|
||||||
|
|
||||||
|
if (item.getDescriptionId() > 0)
|
||||||
|
{
|
||||||
|
mTextSettingDescription.setText(item.getDescriptionId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View clicked)
|
||||||
|
{
|
||||||
|
getAdapter().onSubmenuClick(mItem);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,302 @@
|
|||||||
|
package org.dolphinemu.dolphinemu.utils;
|
||||||
|
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
|
||||||
|
import org.dolphinemu.dolphinemu.model.settings.FloatSetting;
|
||||||
|
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 java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
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 String FILE_NAME_DOLPHIN = "Dolphin";
|
||||||
|
public static final String FILE_NAME_GFX = "GFX";
|
||||||
|
public static final String FILE_NAME_GCPAD = "GCPadNew";
|
||||||
|
public static final String FILE_NAME_WIIMOTE = "WiimoteNew";
|
||||||
|
|
||||||
|
public static final String SECTION_CORE = "Core";
|
||||||
|
|
||||||
|
public static final String SECTION_GFX_SETTINGS = "Settings";
|
||||||
|
public static final String SECTION_GFX_ENHANCEMENTS = "Enhancements";
|
||||||
|
public static final String SECTION_GFX_HACKS = "Hacks";
|
||||||
|
|
||||||
|
public static final String SECTION_STEREOSCOPY = "Stereoscopy";
|
||||||
|
|
||||||
|
public static final String KEY_CPU_CORE = "CPUCore";
|
||||||
|
public static final String KEY_DUAL_CORE = "CPUThread";
|
||||||
|
public static final String KEY_OVERCLOCK_ENABLE = "OverclockEnable";
|
||||||
|
public static final String KEY_OVERCLOCK_PERCENT = "Overclock";
|
||||||
|
public static final String KEY_VIDEO_BACKEND = "GFXBackend";
|
||||||
|
|
||||||
|
public static final String KEY_SHOW_FPS = "ShowFPS";
|
||||||
|
public static final String KEY_INTERNAL_RES = "EFBScale";
|
||||||
|
public static final String KEY_FSAA = "MSAA";
|
||||||
|
public static final String KEY_ANISOTROPY = "MaxAnisotropy";
|
||||||
|
public static final String KEY_POST_SHADER = "PostProcessingShader";
|
||||||
|
public static final String KEY_SCALED_EFB = "EFBScaledCopy";
|
||||||
|
public static final String KEY_PER_PIXEL = "EnablePixelLighting";
|
||||||
|
public static final String KEY_FORCE_FILTERING = "ForceFiltering";
|
||||||
|
public static final String KEY_DISABLE_FOG = "DisableFog";
|
||||||
|
|
||||||
|
public static final String KEY_STEREO_MODE = "StereoMode";
|
||||||
|
public static final String KEY_STEREO_DEPTH = "StereoDepth";
|
||||||
|
public static final String KEY_STEREO_CONV = "StereoConvergencePercentage";
|
||||||
|
public static final String KEY_STEREO_SWAP = "StereoSwapEyes";
|
||||||
|
|
||||||
|
public static final String KEY_SKIP_EFB = "EFBAccessEnable";
|
||||||
|
public static final String KEY_IGNORE_FORMAT = "EFBEmulateFormatChanges";
|
||||||
|
public static final String KEY_EFB_COPY = "EFBCopyEnable";
|
||||||
|
public static final String KEY_EFB_TEXTURE = "EFBToTextureEnable";
|
||||||
|
public static final String KEY_EFB_CACHE = "EFBCopyCacheEnable";
|
||||||
|
public static final String KEY_TEXCACHE_ACCURACY = "SafeTextureCacheColorSamples";
|
||||||
|
public static final String KEY_XFB = "UseXFB";
|
||||||
|
public static final String KEY_XFB_REAL = "UseRealXFB";
|
||||||
|
public static final String KEY_FAST_DEPTH= "FastDepthCalc";
|
||||||
|
public static final String KEY_ASPECT_RATIO= "AspectRatio";
|
||||||
|
|
||||||
|
// Internal only, not actually found in settings file.
|
||||||
|
public static final String KEY_XFB_METHOD = "XFBMethod";
|
||||||
|
|
||||||
|
private 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.
|
||||||
|
*
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
public static Observable<HashMap<String, SettingSection>> readFile(final String fileName)
|
||||||
|
{
|
||||||
|
return Observable.create(new Observable.OnSubscribe<HashMap<String, SettingSection>>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void call(Subscriber<? super HashMap<String, SettingSection>> subscriber)
|
||||||
|
{
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subscriber.onNext(sections);
|
||||||
|
subscriber.onCompleted();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @param fileName The target filename without a path or extension.
|
||||||
|
* @param sections The hashmap containing the Settings we want to serialize.
|
||||||
|
* @return An Observable representing the operation.
|
||||||
|
*/
|
||||||
|
public static Observable<Boolean> saveFile(final String fileName, final HashMap<String, SettingSection> sections)
|
||||||
|
{
|
||||||
|
return Observable.create(new Observable.OnSubscribe<Boolean>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void call(Subscriber<? super Boolean> subscriber)
|
||||||
|
{
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private static File getSettingsFile(String fileName)
|
||||||
|
{
|
||||||
|
String storagePath = Environment.getExternalStorageDirectory().getAbsolutePath();
|
||||||
|
return new File(storagePath + "/dolphin-emu/Config/" + fileName + ".ini");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SettingSection sectionFromLine(String line)
|
||||||
|
{
|
||||||
|
String sectionName = line.substring(1, line.length() - 1);
|
||||||
|
return new SettingSection(sectionName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @return A typed Setting containing the key/value contained in the line.
|
||||||
|
*/
|
||||||
|
private static Setting settingFromLine(SettingSection current, String line)
|
||||||
|
{
|
||||||
|
String[] splitLine = line.split("=");
|
||||||
|
|
||||||
|
String key = splitLine[0].trim();
|
||||||
|
String value = splitLine[1].trim();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int valueAsInt = Integer.valueOf(value);
|
||||||
|
|
||||||
|
return new IntSetting(key, current.getName(), valueAsInt);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
float valueAsFloat = Float.valueOf(value);
|
||||||
|
|
||||||
|
return new FloatSetting(key, current.getName(), valueAsFloat);
|
||||||
|
}
|
||||||
|
catch (NumberFormatException ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case "True":
|
||||||
|
return new BooleanSetting(key, current.getName(), true);
|
||||||
|
case "False":
|
||||||
|
return new BooleanSetting(key, current.getName(), false);
|
||||||
|
default:
|
||||||
|
return new StringSetting(key, current.getName(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
private static void writeSection(PrintWriter writer, SettingSection section)
|
||||||
|
{
|
||||||
|
// Write the section header.
|
||||||
|
String header = sectionAsString(section);
|
||||||
|
writer.println(header);
|
||||||
|
|
||||||
|
// Write this section's values.
|
||||||
|
HashMap<String, Setting> settings = section.getSettings();
|
||||||
|
Set<String> keySet = settings.keySet();
|
||||||
|
|
||||||
|
for (String key : keySet)
|
||||||
|
{
|
||||||
|
Setting setting = settings.get(key);
|
||||||
|
String settingString = settingAsString(setting);
|
||||||
|
|
||||||
|
writer.println(settingString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String sectionAsString(SettingSection section)
|
||||||
|
{
|
||||||
|
return "[" + section.getName() + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String settingAsString(Setting setting)
|
||||||
|
{
|
||||||
|
return setting.getKey() + " = " + setting.getValueAsString();
|
||||||
|
}
|
||||||
|
}
|
@ -1,128 +0,0 @@
|
|||||||
package org.dolphinemu.dolphinemu.utils;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.DialogPreference;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.SeekBar;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
|
|
||||||
public class SliderPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener, View.OnClickListener
|
|
||||||
{
|
|
||||||
private static final String androidns = "http://schemas.android.com/apk/res/android";
|
|
||||||
|
|
||||||
// SeekBar
|
|
||||||
private int m_max, m_value;
|
|
||||||
private String m_key;
|
|
||||||
private SeekBar m_seekbar;
|
|
||||||
|
|
||||||
// TextView
|
|
||||||
private TextView m_textview;
|
|
||||||
|
|
||||||
public SliderPreference(Context context, AttributeSet attrs)
|
|
||||||
{
|
|
||||||
super(context, attrs);
|
|
||||||
|
|
||||||
// Seekbar values
|
|
||||||
m_value = attrs.getAttributeIntValue(androidns, "defaultValue", 0);
|
|
||||||
m_max = attrs.getAttributeIntValue(androidns, "max", 100);
|
|
||||||
m_key = attrs.getAttributeValue(androidns, "key");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected View onCreateDialogView()
|
|
||||||
{
|
|
||||||
LayoutInflater inflater = LayoutInflater.from(getContext());
|
|
||||||
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.slider_layout, null, false);
|
|
||||||
|
|
||||||
m_seekbar = (SeekBar) layout.findViewById(R.id.sliderSeekBar);
|
|
||||||
m_textview = (TextView) layout.findViewById(R.id.sliderTextView);
|
|
||||||
|
|
||||||
if (shouldPersist())
|
|
||||||
{
|
|
||||||
if (m_key != null && m_key.equals("Overclock"))
|
|
||||||
{
|
|
||||||
Toast.makeText(getContext(), getContext().getString(R.string.overclock_warning),
|
|
||||||
Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
float valueAsFloat = Float.valueOf(getPersistedString(Integer.toString(m_value)));
|
|
||||||
float valueAsPercent = valueAsFloat * 100;
|
|
||||||
|
|
||||||
m_value = Math.round(valueAsPercent);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_value = Integer.valueOf(getPersistedString(Integer.toString(m_value)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_seekbar.setMax(m_max);
|
|
||||||
m_seekbar.setProgress(m_value);
|
|
||||||
setProgressText(m_value);
|
|
||||||
m_seekbar.setOnSeekBarChangeListener(this);
|
|
||||||
|
|
||||||
return layout;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SeekBar overrides
|
|
||||||
@Override
|
|
||||||
public void onProgressChanged(SeekBar seek, int value, boolean fromTouch)
|
|
||||||
{
|
|
||||||
m_value = value;
|
|
||||||
setProgressText(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStartTrackingTouch(SeekBar seek)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStopTrackingTouch(SeekBar seek)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void setProgressText(int value)
|
|
||||||
{
|
|
||||||
m_textview.setText(String.valueOf(value));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void showDialog(Bundle state)
|
|
||||||
{
|
|
||||||
super.showDialog(state);
|
|
||||||
|
|
||||||
Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
|
|
||||||
positiveButton.setOnClickListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View v)
|
|
||||||
{
|
|
||||||
if (shouldPersist())
|
|
||||||
{
|
|
||||||
String valueToSave;
|
|
||||||
if (m_key != null && m_key.equals("Overclock"))
|
|
||||||
{
|
|
||||||
float valueAsFloat = m_value / 100.0f;
|
|
||||||
valueToSave = Float.toString(valueAsFloat);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
valueToSave = Integer.toString(m_seekbar.getProgress());
|
|
||||||
}
|
|
||||||
|
|
||||||
persistString(valueToSave);
|
|
||||||
callChangeListener(m_seekbar.getProgress());
|
|
||||||
}
|
|
||||||
((AlertDialog) getDialog()).dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,495 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013 Dolphin Emulator Project
|
|
||||||
* Licensed under GPLv2+
|
|
||||||
* Refer to the license.txt file included.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.utils;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class that retrieves all of the set user preferences in Android, in a safe way.
|
|
||||||
* <p>
|
|
||||||
* If any preferences are added to this emulator, an accessor for that preference
|
|
||||||
* should be added here. This way lengthy calls to getters from SharedPreferences
|
|
||||||
* aren't made necessary.
|
|
||||||
*/
|
|
||||||
public final class UserPreferences
|
|
||||||
{
|
|
||||||
private UserPreferences()
|
|
||||||
{
|
|
||||||
// Disallows instantiation.
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the settings stored in the Dolphin ini config files to the shared preferences of this front-end.
|
|
||||||
*
|
|
||||||
* @param ctx The context used to retrieve the SharedPreferences instance.
|
|
||||||
*/
|
|
||||||
public static void LoadIniToPrefs(Context ctx)
|
|
||||||
{
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
|
||||||
|
|
||||||
// Get an editor.
|
|
||||||
SharedPreferences.Editor editor = prefs.edit();
|
|
||||||
|
|
||||||
// Add the settings.
|
|
||||||
if (Build.CPU_ABI.contains("arm64"))
|
|
||||||
editor.putString("cpuCorePref", getConfig("Dolphin.ini", "Core", "CPUCore", "4"));
|
|
||||||
else
|
|
||||||
editor.putString("cpuCorePref", getConfig("Dolphin.ini", "Core", "CPUCore", "3"));
|
|
||||||
|
|
||||||
editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "True").equals("True"));
|
|
||||||
editor.putBoolean("OverclockEnable", getConfig("Dolphin.ini", "Core", "OverclockEnable", "False").equals("True"));
|
|
||||||
editor.putString("Overclock", getConfig("Dolphin.ini", "Core", "Overclock", "100"));
|
|
||||||
|
|
||||||
// Load analog ranges from GCPadNew.ini and WiimoteNew.ini
|
|
||||||
editor.putString("mainRadius0", getConfig("GCPadNew.ini", "GCPad1", "Main Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("cStickRadius0", getConfig("GCPadNew.ini", "GCPad1", "C-Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("inputThres0", getConfig("GCPadNew.ini", "GCPad1", "Triggers/Threshold", "90,000000"));
|
|
||||||
editor.putString("mainRadius1", getConfig("GCPadNew.ini", "GCPad2", "Main Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("cStickRadius1", getConfig("GCPadNew.ini", "GCPad2", "C-Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("inputThres1", getConfig("GCPadNew.ini", "GCPad2", "Triggers/Threshold", "90,000000"));
|
|
||||||
editor.putString("mainRadius2", getConfig("GCPadNew.ini", "GCPad3", "Main Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("cStickRadius2", getConfig("GCPadNew.ini", "GCPad3", "C-Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("inputThres2", getConfig("GCPadNew.ini", "GCPad3", "Triggers/Threshold", "90,000000"));
|
|
||||||
editor.putString("mainRadius3", getConfig("GCPadNew.ini", "GCPad4", "Main Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("cStickRadius3", getConfig("GCPadNew.ini", "GCPad4", "C-Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("inputThres3", getConfig("GCPadNew.ini", "GCPad4", "Triggers/Threshold", "90,000000"));
|
|
||||||
|
|
||||||
editor.putString("tiltRange4", getConfig("WiimoteNew.ini", "Wiimote1", "Tilt/Modifier/Range", "50,00000"));
|
|
||||||
editor.putString("tiltRange5", getConfig("WiimoteNew.ini", "Wiimote2", "Tilt/Modifier/Range", "50,00000"));
|
|
||||||
editor.putString("tiltRange6", getConfig("WiimoteNew.ini", "Wiimote3", "Tilt/Modifier/Range", "50,00000"));
|
|
||||||
editor.putString("tiltRange7", getConfig("WiimoteNew.ini", "Wiimote4", "Tilt/Modifier/Range", "50,00000"));
|
|
||||||
|
|
||||||
editor.putString("nunchukRadius4", getConfig("WiimoteNew.ini", "Wiimote1", "Nunchuk/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("nunchukRange4", getConfig("WiimoteNew.ini", "Wiimote1", "Nunchuk/Tilt/Modifier/Range", "50,00000"));
|
|
||||||
editor.putString("nunchukRadius5", getConfig("WiimoteNew.ini", "Wiimote2", "Nunchuk/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("nunchukRange5", getConfig("WiimoteNew.ini", "Wiimote2", "Nunchuk/Tilt/Modifier/Range", "50,00000"));
|
|
||||||
editor.putString("nunchukRadius6", getConfig("WiimoteNew.ini", "Wiimote3", "Nunchuk/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("nunchukRange6", getConfig("WiimoteNew.ini", "Wiimote3", "Nunchuk/Tilt/Modifier/Range", "50,00000"));
|
|
||||||
editor.putString("nunchukRadius7", getConfig("WiimoteNew.ini", "Wiimote4", "Nunchuk/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("nunchukRange7", getConfig("WiimoteNew.ini", "Wiimote4", "Nunchuk/Tilt/Modifier/Range", "50,00000"));
|
|
||||||
|
|
||||||
editor.putString("classicLRadius4", getConfig("WiimoteNew.ini", "Wiimote1", "Classic/Left Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicRRadius4", getConfig("WiimoteNew.ini", "Wiimote1", "Classic/Right Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicThres4", getConfig("WiimoteNew.ini", "Wiimote1", "Classic/Triggers/Threshold", "90,000000"));
|
|
||||||
editor.putString("classicLRadius5", getConfig("WiimoteNew.ini", "Wiimote2", "Classic/Left Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicRRadius5", getConfig("WiimoteNew.ini", "Wiimote2", "Classic/Right Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicThres5", getConfig("WiimoteNew.ini", "Wiimote2", "Classic/Triggers/Threshold", "90,000000"));
|
|
||||||
editor.putString("classicLRadius6", getConfig("WiimoteNew.ini", "Wiimote3", "Classic/Left Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicRRadius6", getConfig("WiimoteNew.ini", "Wiimote3", "Classic/Right Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicThres6", getConfig("WiimoteNew.ini", "Wiimote3", "Classic/Triggers/Threshold", "90,000000"));
|
|
||||||
editor.putString("classicLRadius7", getConfig("WiimoteNew.ini", "Wiimote4", "Classic/Left Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicRRadius7", getConfig("WiimoteNew.ini", "Wiimote4", "Classic/Right Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("classicThres7", getConfig("WiimoteNew.ini", "Wiimote4", "Classic/Triggers/Threshold", "90,000000"));
|
|
||||||
|
|
||||||
editor.putString("guitarRadius4", getConfig("WiimoteNew.ini", "Wiimote1", "Guitar/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("guitarRadius5", getConfig("WiimoteNew.ini", "Wiimote2", "Guitar/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("guitarRadius6", getConfig("WiimoteNew.ini", "Wiimote3", "Guitar/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("guitarRadius7", getConfig("WiimoteNew.ini", "Wiimote4", "Guitar/Stick/Radius", "100,000000"));
|
|
||||||
|
|
||||||
editor.putString("drumsRadius4", getConfig("WiimoteNew.ini", "Wiimote1", "Drums/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("drumsRadius5", getConfig("WiimoteNew.ini", "Wiimote2", "Drums/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("drumsRadius6", getConfig("WiimoteNew.ini", "Wiimote3", "Drums/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("drumsRadius7", getConfig("WiimoteNew.ini", "Wiimote4", "Drums/Stick/Radius", "100,000000"));
|
|
||||||
|
|
||||||
editor.putString("turntableRadius4", getConfig("WiimoteNew.ini", "Wiimote1", "Turntable/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("turntableRadius5", getConfig("WiimoteNew.ini", "Wiimote2", "Turntable/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("turntableRadius6", getConfig("WiimoteNew.ini", "Wiimote3", "Turntable/Stick/Radius", "100,000000"));
|
|
||||||
editor.putString("turntableRadius7", getConfig("WiimoteNew.ini", "Wiimote4", "Turntable/Stick/Radius", "100,000000"));
|
|
||||||
|
|
||||||
// Load Wiimote Extension settings from WiimoteNew.ini
|
|
||||||
editor.putString("wiimoteExtension4", getConfig("WiimoteNew.ini", "Wiimote1", "Extension", "None"));
|
|
||||||
editor.putString("wiimoteExtension5", getConfig("WiimoteNew.ini", "Wiimote2", "Extension", "None"));
|
|
||||||
editor.putString("wiimoteExtension6", getConfig("WiimoteNew.ini", "Wiimote3", "Extension", "None"));
|
|
||||||
editor.putString("wiimoteExtension7", getConfig("WiimoteNew.ini", "Wiimote4", "Extension", "None"));
|
|
||||||
|
|
||||||
editor.putString("gpuPref", getConfig("Dolphin.ini", "Core", "GFXBackend", "OGL"));
|
|
||||||
editor.putBoolean("showFPS", getConfig("GFX.ini", "Settings", "ShowFPS", "False").equals("True"));
|
|
||||||
editor.putBoolean("drawOnscreenControls", getConfig("Dolphin.ini", "Android", "ScreenControls", "True").equals("True"));
|
|
||||||
|
|
||||||
editor.putString("internalResolution", getConfig("GFX.ini", "Settings", "EFBScale", "2"));
|
|
||||||
editor.putString("FSAA", getConfig("GFX.ini", "Settings", "MSAA", "0"));
|
|
||||||
editor.putString("anisotropicFiltering", getConfig("GFX.ini", "Enhancements", "MaxAnisotropy", "0"));
|
|
||||||
editor.putString("postProcessingShader", getConfig("GFX.ini", "Enhancements", "PostProcessingShader", ""));
|
|
||||||
editor.putBoolean("scaledEFBCopy", getConfig("GFX.ini", "Hacks", "EFBScaledCopy", "True").equals("True"));
|
|
||||||
editor.putBoolean("perPixelLighting", getConfig("GFX.ini", "Settings", "EnablePixelLighting", "False").equals("True"));
|
|
||||||
editor.putBoolean("forceTextureFiltering", getConfig("GFX.ini", "Enhancements", "ForceFiltering", "False").equals("True"));
|
|
||||||
editor.putBoolean("disableFog", getConfig("GFX.ini", "Settings", "DisableFog", "False").equals("True"));
|
|
||||||
editor.putBoolean("skipEFBAccess", getConfig("GFX.ini", "Hacks", "EFBAccessEnable", "False").equals("True"));
|
|
||||||
editor.putBoolean("ignoreFormatChanges", getConfig("GFX.ini", "Hacks", "EFBEmulateFormatChanges", "False").equals("True"));
|
|
||||||
editor.putString("stereoscopyMode", getConfig("GFX.ini", "Stereoscopy", "StereoMode", "0"));
|
|
||||||
editor.putBoolean("stereoSwapEyes", getConfig("GFX.ini", "Stereoscopy", "StereoSwapEyes", "False").equals("True"));
|
|
||||||
editor.putString("stereoDepth", getConfig("GFX.ini", "Stereoscopy", "StereoDepth", "20"));
|
|
||||||
editor.putString("stereoConvergencePercentage", getConfig("GFX.ini", "Stereoscopy", "StereoConvergencePercentage", "100"));
|
|
||||||
editor.putBoolean("enableController1", getConfig("Dolphin.ini", "Core", "SIDevice0", "6") == "6");
|
|
||||||
editor.putBoolean("enableController2", getConfig("Dolphin.ini", "Core", "SIDevice1", "0") == "6");
|
|
||||||
editor.putBoolean("enableController3", getConfig("Dolphin.ini", "Core", "SIDevice2", "0") == "6");
|
|
||||||
editor.putBoolean("enableController4", getConfig("Dolphin.ini", "Core", "SIDevice3", "0") == "6");
|
|
||||||
|
|
||||||
String efbCopyOn = getConfig("GFX.ini", "Hacks", "EFBCopyEnable", "True");
|
|
||||||
String efbToTexture = getConfig("GFX.ini", "Hacks", "EFBToTextureEnable", "True");
|
|
||||||
String efbCopyCache = getConfig("GFX.ini", "Hacks", "EFBCopyCacheEnable", "False");
|
|
||||||
|
|
||||||
if (efbCopyOn.equals("False"))
|
|
||||||
{
|
|
||||||
editor.putString("efbCopyMethod", "Off");
|
|
||||||
}
|
|
||||||
else if (efbCopyOn.equals("True") && efbToTexture.equals("True"))
|
|
||||||
{
|
|
||||||
editor.putString("efbCopyMethod", "Texture");
|
|
||||||
}
|
|
||||||
else if(efbCopyOn.equals("True") && efbToTexture.equals("False") && efbCopyCache.equals("False"))
|
|
||||||
{
|
|
||||||
editor.putString("efbCopyMethod", "RAM (uncached)");
|
|
||||||
}
|
|
||||||
else if(efbCopyOn.equals("True") && efbToTexture.equals("False") && efbCopyCache.equals("True"))
|
|
||||||
{
|
|
||||||
editor.putString("efbCopyMethod", "RAM (cached)");
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.putString("textureCacheAccuracy", getConfig("GFX.ini", "Settings", "SafeTextureCacheColorSamples", "128"));
|
|
||||||
|
|
||||||
String usingXFB = getConfig("GFX.ini", "Settings", "UseXFB", "False");
|
|
||||||
String usingRealXFB = getConfig("GFX.ini", "Settings", "UseRealXFB", "False");
|
|
||||||
|
|
||||||
if (usingXFB.equals("False"))
|
|
||||||
{
|
|
||||||
editor.putString("externalFrameBuffer", "Disabled");
|
|
||||||
}
|
|
||||||
else if (usingXFB.equals("True") && usingRealXFB.equals("False"))
|
|
||||||
{
|
|
||||||
editor.putString("externalFrameBuffer", "Virtual");
|
|
||||||
}
|
|
||||||
else if (usingXFB.equals("True") && usingRealXFB.equals("True"))
|
|
||||||
{
|
|
||||||
editor.putString("externalFrameBuffer", "Real");
|
|
||||||
}
|
|
||||||
|
|
||||||
editor.putBoolean("fastDepthCalculation", getConfig("GFX.ini", "Settings", "FastDepthCalc", "True").equals("True"));
|
|
||||||
editor.putString("aspectRatio", getConfig("GFX.ini", "Settings", "AspectRatio", "0"));
|
|
||||||
|
|
||||||
// Apply the changes.
|
|
||||||
editor.apply();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Small utility method that shortens calls to NativeLibrary.GetConfig.
|
|
||||||
private static String getConfig(String ini, String section, String key, String defaultValue)
|
|
||||||
{
|
|
||||||
return NativeLibrary.GetConfig(ini, section, key, defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the preferences set in the front-end to the Dolphin ini files.
|
|
||||||
*
|
|
||||||
* @param ctx The context used to retrieve the user settings.
|
|
||||||
* */
|
|
||||||
public static void SavePrefsToIni(Context ctx)
|
|
||||||
{
|
|
||||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
|
||||||
|
|
||||||
// Whether or not the user is using dual core.
|
|
||||||
boolean isUsingDualCore = prefs.getBoolean("dualCorePref", true);
|
|
||||||
|
|
||||||
// Current CPU core being used. Falls back to interpreter upon error.
|
|
||||||
String currentEmuCore = prefs.getString("cpuCorePref", "0");
|
|
||||||
|
|
||||||
boolean overclockEnabled = prefs.getBoolean("OverclockEnable", false);
|
|
||||||
String overclockSetting = prefs.getString("Overclock", "100");
|
|
||||||
|
|
||||||
// Current GC analog range setup. Falls back to default upon error.
|
|
||||||
String currentMainRadius0 = prefs.getString("mainRadius0", "100,000000");
|
|
||||||
String currentCStickRadius0 = prefs.getString("cStickRadius0", "100,000000");
|
|
||||||
String currentInputThres0 = prefs.getString("inputThres0", "90,000000");
|
|
||||||
String currentMainRadius1 = prefs.getString("mainRadius1", "100,000000");
|
|
||||||
String currentCStickRadius1 = prefs.getString("cStickRadius1", "100,000000");
|
|
||||||
String currentInputThres1 = prefs.getString("inputThres1", "90,000000");
|
|
||||||
String currentMainRadius2 = prefs.getString("mainRadius2", "100,000000");
|
|
||||||
String currentCStickRadius2 = prefs.getString("cStickRadius2", "100,000000");
|
|
||||||
String currentInputThres2 = prefs.getString("inputThres2", "90,000000");
|
|
||||||
String currentMainRadius3 = prefs.getString("mainRadius3", "100,000000");
|
|
||||||
String currentCStickRadius3 = prefs.getString("cStickRadius3", "100,000000");
|
|
||||||
String currentInputThres3 = prefs.getString("inputThres3", "90,000000");
|
|
||||||
|
|
||||||
// Current Wii analog range setup. Falls back to default on error.
|
|
||||||
String currentTiltRange4 = prefs.getString("tiltRange4", "50,000000");
|
|
||||||
String currentTiltRange5 = prefs.getString("tiltRange5", "50,000000");
|
|
||||||
String currentTiltRange6 = prefs.getString("tiltRange6", "50,000000");
|
|
||||||
String currentTiltRange7 = prefs.getString("tiltRange7", "50,000000");
|
|
||||||
|
|
||||||
// Current Nunchuk analog range setup. Falls back to default upon error.
|
|
||||||
String currentNunchukRadius4 = prefs.getString("nunchukRadius4", "100,000000");
|
|
||||||
String currentNunchukRange4 = prefs.getString("nunchukRange4", "50,000000");
|
|
||||||
String currentNunchukRadius5 = prefs.getString("nunchukRadius5", "100,000000");
|
|
||||||
String currentNunchukRange5 = prefs.getString("nunchukRange5", "50,000000");
|
|
||||||
String currentNunchukRadius6 = prefs.getString("nunchukRadius6", "100,000000");
|
|
||||||
String currentNunchukRange6 = prefs.getString("nunchukRange6", "50,000000");
|
|
||||||
String currentNunchukRadius7 = prefs.getString("nunchukRadius7", "100,000000");
|
|
||||||
String currentNunchukRange7 = prefs.getString("nunchukRange7", "50,000000");
|
|
||||||
|
|
||||||
// Current Classic analog range setup. Falls back to 100,000000 upon error.
|
|
||||||
String currentClassicLRadius4 = prefs.getString("classicLRadius4", "100,000000");
|
|
||||||
String currentClassicRRadius4 = prefs.getString("classicRRadius4", "100,000000");
|
|
||||||
String currentClassicThres4 = prefs.getString("classicThres4", "90,000000");
|
|
||||||
String currentClassicLRadius5 = prefs.getString("classicLRadius5", "100,000000");
|
|
||||||
String currentClassicRRadius5 = prefs.getString("classicRRadius5", "100,000000");
|
|
||||||
String currentClassicThres5 = prefs.getString("classicThres5", "90,000000");
|
|
||||||
String currentClassicLRadius6 = prefs.getString("classicLRadius6", "100,000000");
|
|
||||||
String currentClassicRRadius6 = prefs.getString("classicRRadius6", "100,000000");
|
|
||||||
String currentClassicThres6 = prefs.getString("classicThres6", "90,000000");
|
|
||||||
String currentClassicLRadius7 = prefs.getString("classicLRadius7", "100,000000");
|
|
||||||
String currentClassicRRadius7 = prefs.getString("classicRRadius7", "100,000000");
|
|
||||||
String currentClassicThres7 = prefs.getString("classicThres7", "90,000000");
|
|
||||||
|
|
||||||
// Current Guitar analog range setup. Falls back to default upon error.
|
|
||||||
String currentGuitarRadius4 = prefs.getString("guitarRadius4", "100,000000");
|
|
||||||
String currentGuitarRadius5 = prefs.getString("guitarRadius5", "100,000000");
|
|
||||||
String currentGuitarRadius6 = prefs.getString("guitarRadius6", "100,000000");
|
|
||||||
String currentGuitarRadius7 = prefs.getString("guitarRadius7", "100,000000");
|
|
||||||
|
|
||||||
// Current Drums modifier Radius setup. Falls back to default upon error.
|
|
||||||
String currentDrumsRadius4 = prefs.getString("drumsRadius4", "100,000000");
|
|
||||||
String currentDrumsRadius5 = prefs.getString("drumsRadius5", "100,000000");
|
|
||||||
String currentDrumsRadius6 = prefs.getString("drumsRadius6", "100,000000");
|
|
||||||
String currentDrumsRadius7 = prefs.getString("drumsRadius7", "100,000000");
|
|
||||||
|
|
||||||
// Current Turntable analog range setup. Falls back to default upon error.
|
|
||||||
String currentTurntableRadius4 = prefs.getString("turntableRadius4", "100,000000");
|
|
||||||
String currentTurntableRadius5 = prefs.getString("turntableRadius5", "100,000000");
|
|
||||||
String currentTurntableRadius6 = prefs.getString("turntableRadius6", "100,000000");
|
|
||||||
String currentTurntableRadius7 = prefs.getString("turntableRadius7", "100,000000");
|
|
||||||
|
|
||||||
// Current wiimote extension setup. Falls back to no extension upon error.
|
|
||||||
String currentWiimoteExtension4 = prefs.getString("wiimoteExtension4", "None");
|
|
||||||
String currentWiimoteExtension5 = prefs.getString("wiimoteExtension5", "None");
|
|
||||||
String currentWiimoteExtension6 = prefs.getString("wiimoteExtension6", "None");
|
|
||||||
String currentWiimoteExtension7 = prefs.getString("wiimoteExtension7", "None");
|
|
||||||
|
|
||||||
// Current video backend being used. Falls back to software rendering upon error.
|
|
||||||
String currentVideoBackend = prefs.getString("gpuPref", "Software Rendering");
|
|
||||||
|
|
||||||
// Whether or not FPS will be displayed on-screen.
|
|
||||||
boolean showingFPS = prefs.getBoolean("showFPS", false);
|
|
||||||
|
|
||||||
// Whether or not to draw on-screen controls.
|
|
||||||
boolean drawingOnscreenControls = prefs.getBoolean("drawOnscreenControls", true);
|
|
||||||
|
|
||||||
// Whether or not to ignore all EFB access requests from the CPU.
|
|
||||||
boolean skipEFBAccess = prefs.getBoolean("skipEFBAccess", false);
|
|
||||||
|
|
||||||
// Whether or not to ignore changes to the EFB format.
|
|
||||||
boolean ignoreFormatChanges = prefs.getBoolean("ignoreFormatChanges", false);
|
|
||||||
|
|
||||||
// EFB copy method to use.
|
|
||||||
String efbCopyMethod = prefs.getString("efbCopyMethod", "Texture");
|
|
||||||
|
|
||||||
// Texture cache accuracy. Falls back to "Fast" up error.
|
|
||||||
String textureCacheAccuracy = prefs.getString("textureCacheAccuracy", "128");
|
|
||||||
|
|
||||||
// External frame buffer emulation. Falls back to disabled upon error.
|
|
||||||
String externalFrameBuffer = prefs.getString("externalFrameBuffer", "Disabled");
|
|
||||||
|
|
||||||
// Whether or not to use fast depth calculation.
|
|
||||||
boolean useFastDepthCalc = prefs.getBoolean("fastDepthCalculation", true);
|
|
||||||
|
|
||||||
// Aspect ratio selection
|
|
||||||
String aspectRatio = prefs.getString("aspectRatio", "0");
|
|
||||||
|
|
||||||
// Internal resolution. Falls back to 1x Native upon error.
|
|
||||||
String internalResolution = prefs.getString("internalResolution", "2");
|
|
||||||
|
|
||||||
// FSAA Level. Falls back to 1x upon error.
|
|
||||||
String FSAALevel = prefs.getString("FSAA", "0");
|
|
||||||
|
|
||||||
// Anisotropic Filtering Level. Falls back to 1x upon error.
|
|
||||||
String anisotropicFiltLevel = prefs.getString("anisotropicFiltering", "0");
|
|
||||||
|
|
||||||
// Post processing shader setting
|
|
||||||
String postProcessing = prefs.getString("postProcessingShader", "");
|
|
||||||
|
|
||||||
// Whether or not Scaled EFB copies are used.
|
|
||||||
boolean usingScaledEFBCopy = prefs.getBoolean("scaledEFBCopy", true);
|
|
||||||
|
|
||||||
// Whether or not per-pixel lighting is used.
|
|
||||||
boolean usingPerPixelLighting = prefs.getBoolean("perPixelLighting", false);
|
|
||||||
|
|
||||||
// Whether or not texture filtering is being forced.
|
|
||||||
boolean isForcingTextureFiltering = prefs.getBoolean("forceTextureFiltering", false);
|
|
||||||
|
|
||||||
// Whether or not fog is disabled.
|
|
||||||
boolean fogIsDisabled = prefs.getBoolean("disableFog", false);
|
|
||||||
|
|
||||||
// Stereoscopy setting
|
|
||||||
String stereoscopyMode = prefs.getString("stereoscopyMode", "0");
|
|
||||||
|
|
||||||
// Stereoscopy swap eyes
|
|
||||||
boolean stereoscopyEyeSwap = prefs.getBoolean("stereoSwapEyes", false);
|
|
||||||
|
|
||||||
// Stereoscopy separation
|
|
||||||
String stereoscopySeparation = prefs.getString("stereoDepth", "20");
|
|
||||||
|
|
||||||
// Stereoscopy convergence
|
|
||||||
String stereoConvergencePercentage = prefs.getString("stereoConvergencePercentage", "100");
|
|
||||||
|
|
||||||
// Controllers
|
|
||||||
// Controller 1 never gets disconnected due to touch screen
|
|
||||||
//boolean enableController1 = prefs.getBoolean("enableController1", true);
|
|
||||||
boolean enableController2 = prefs.getBoolean("enableController2", false);
|
|
||||||
boolean enableController3 = prefs.getBoolean("enableController3", false);
|
|
||||||
boolean enableController4 = prefs.getBoolean("enableController4", false);
|
|
||||||
|
|
||||||
// CPU related Settings
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUCore", currentEmuCore);
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUThread", isUsingDualCore ? "True" : "False");
|
|
||||||
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "OverclockEnable", overclockEnabled ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "Overclock", overclockSetting);
|
|
||||||
|
|
||||||
// GameCube analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad1", "Main Stick/Radius", currentMainRadius0);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad1", "C-Stick/Radius", currentCStickRadius0);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad1", "Triggers/Threshold", currentInputThres0);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad2", "Main Stick/Radius", currentMainRadius1);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad2", "C-Stick/Radius", currentCStickRadius1);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad2", "Triggers/Threshold", currentInputThres1);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad3", "Main Stick/Radius", currentMainRadius2);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad3", "C-Stick/Radius", currentCStickRadius2);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad3", "Triggers/Threshold", currentInputThres2);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad4", "Main Stick/Radius", currentMainRadius3);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad4", "C-Stick/Radius", currentCStickRadius3);
|
|
||||||
NativeLibrary.SetConfig("GCPadNew.ini", "GCPad4", "Triggers/Threshold", currentInputThres3);
|
|
||||||
|
|
||||||
// Wiimote analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Tilt/Modifier/Range", currentTiltRange4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Tilt/Modifier/Range", currentTiltRange5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Tilt/Modifier/Range", currentTiltRange6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Tilt/Modifier/Range", currentTiltRange7);
|
|
||||||
|
|
||||||
// Nunchuk analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Nunchuk/Stick/Radius", currentNunchukRadius4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Nunchuk/Stick/Radius", currentNunchukRange4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Nunchuk/Stick/Radius", currentNunchukRadius5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Nunchuk/Stick/Radius", currentNunchukRange5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Nunchuk/Stick/Radius", currentNunchukRadius6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Nunchuk/Stick/Radius", currentNunchukRange6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Nunchuk/Stick/Radius", currentNunchukRadius7);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Nunchuk/Stick/Radius", currentNunchukRange7);
|
|
||||||
|
|
||||||
// Classic analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Classic/Left Stick/Radius", currentClassicLRadius4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Classic/Right Stick/Radius", currentClassicRRadius4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Classic/Triggers/Threshold", currentClassicThres4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Classic/Left Stick/Radius", currentClassicLRadius5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Classic/Right Stick/Radius", currentClassicRRadius5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Classic/Triggers/Threshold", currentClassicThres5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Classic/Left Stick/Radius", currentClassicLRadius6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Classic/Right Stick/Radius", currentClassicRRadius6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Classic/Triggers/Threshold", currentClassicThres6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Classic/Left Stick/Radius", currentClassicLRadius7);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Classic/Right Stick/Radius", currentClassicRRadius7);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Classic/Triggers/Threshold", currentClassicThres7);
|
|
||||||
|
|
||||||
// Guitar analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Guitar/Stick/Radius", currentGuitarRadius4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Guitar/Stick/Radius", currentGuitarRadius5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Guitar/Stick/Radius", currentGuitarRadius6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Guitar/Stick/Radius", currentGuitarRadius7);
|
|
||||||
|
|
||||||
// Drums analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Drums/Stick/Radius", currentDrumsRadius4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Drums/Stick/Radius", currentDrumsRadius5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Drums/Stick/Radius", currentDrumsRadius6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Drums/Stick/Radius", currentDrumsRadius7);
|
|
||||||
|
|
||||||
// Turntable analog ranges Setup
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Turntable/Stick/Radius", currentTurntableRadius4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Turntable/Stick/Radius", currentTurntableRadius5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Turntable/Stick/Radius", currentTurntableRadius6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Turntable/Stick/Radius", currentTurntableRadius7);
|
|
||||||
|
|
||||||
// Wiimote Extension Settings
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Extension", currentWiimoteExtension4);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote2", "Extension", currentWiimoteExtension5);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote3", "Extension", currentWiimoteExtension6);
|
|
||||||
NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote4", "Extension", currentWiimoteExtension7);
|
|
||||||
|
|
||||||
// General Video Settings
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "GFXBackend", currentVideoBackend);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "ShowFPS", showingFPS ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Android", "ScreenControls", drawingOnscreenControls ? "True" : "False");
|
|
||||||
|
|
||||||
// Video Hack Settings
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBAccessEnable", skipEFBAccess ? "False" : "True");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBEmulateFormatChanges", ignoreFormatChanges ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "AspectRatio", aspectRatio);
|
|
||||||
|
|
||||||
// Set EFB Copy Method
|
|
||||||
if (efbCopyMethod.equals("Off"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBCopyEnable", "False");
|
|
||||||
}
|
|
||||||
else if (efbCopyMethod.equals("Texture"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBCopyEnable", "True");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBToTextureEnable", "True");
|
|
||||||
}
|
|
||||||
else if (efbCopyMethod.equals("RAM (uncached)"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBCopyEnable", "True");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBToTextureEnable", "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBCopyCacheEnable", "False");
|
|
||||||
}
|
|
||||||
else if (efbCopyMethod.equals("RAM (cached)"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBCopyEnable", "True");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBToTextureEnable", "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBCopyCacheEnable", "True");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set texture cache accuracy
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "SafeTextureCacheColorSamples", textureCacheAccuracy);
|
|
||||||
|
|
||||||
// Set external frame buffer.
|
|
||||||
if (externalFrameBuffer.equals("Disabled"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "UseXFB", "False");
|
|
||||||
}
|
|
||||||
else if (externalFrameBuffer.equals("Virtual"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "UseXFB", "True");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "UseRealXFB", "False");
|
|
||||||
}
|
|
||||||
else if (externalFrameBuffer.equals("Real"))
|
|
||||||
{
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "UseXFB", "True");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "UseRealXFB", "True");
|
|
||||||
}
|
|
||||||
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "FastDepthCalc", useFastDepthCalc ? "True" : "False");
|
|
||||||
|
|
||||||
//-- Enhancement Settings --//
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "EFBScale", internalResolution);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "MSAA", FSAALevel);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Enhancements", "MaxAnisotropy", anisotropicFiltLevel);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Enhancements", "PostProcessingShader", postProcessing);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Hacks", "EFBScaledCopy", usingScaledEFBCopy ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "EnablePixelLighting", usingPerPixelLighting ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Enhancements", "ForceFiltering", isForcingTextureFiltering ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Settings", "DisableFog", fogIsDisabled ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Stereoscopy", "StereoMode", stereoscopyMode);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Stereoscopy", "StereoSwapEyes", stereoscopyEyeSwap ? "True" : "False");
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Stereoscopy", "StereoDepth", stereoscopySeparation);
|
|
||||||
NativeLibrary.SetConfig("GFX.ini", "Stereoscopy", "StereoConvergence", stereoConvergencePercentage);
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "SIDevice0", "6");
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "SIDevice1", enableController2 ? "6" : "0");
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "SIDevice2", enableController3 ? "6" : "0");
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", "Core", "SIDevice3", enableController4 ? "6" : "0");
|
|
||||||
}
|
|
||||||
}
|
|
Before Width: | Height: | Size: 561 B |
After Width: | Height: | Size: 259 B |
After Width: | Height: | Size: 304 B |
Before Width: | Height: | Size: 737 B |
After Width: | Height: | Size: 225 B |
After Width: | Height: | Size: 360 B |
Before Width: | Height: | Size: 974 B |
After Width: | Height: | Size: 333 B |
After Width: | Height: | Size: 570 B |
Before Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 759 B |
BIN
Source/Android/app/src/main/res/drawable/ic_settings_core_tv.png
Normal file
After Width: | Height: | Size: 432 B |
After Width: | Height: | Size: 759 B |
Before Width: | Height: | Size: 2.2 KiB |
@ -1,20 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
android:layout_width="match_parent"
|
||||||
android:layout_width="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:id="@+id/frame_content"/>
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@+id/frame_content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_marginLeft="@dimen/activity_horizontal_margin"
|
|
||||||
android:layout_marginRight="@dimen/activity_horizontal_margin"
|
|
||||||
tools:listitem="@layout/list_item_file"
|
|
||||||
android:elevation="4dp"
|
|
||||||
android:background="@android:color/white"/>
|
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
37
Source/Android/app/src/main/res/layout/dialog_seekbar.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/spacing_xlarge"
|
||||||
|
android:layout_marginRight="@dimen/spacing_xlarge"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_below="@+id/text_value"
|
||||||
|
android:layout_marginBottom="@dimen/spacing_xlarge"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="75"
|
||||||
|
android:id="@+id/text_value"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginTop="@dimen/spacing_xlarge"
|
||||||
|
android:layout_marginBottom="@dimen/spacing_large"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="%"
|
||||||
|
android:id="@+id/text_units"
|
||||||
|
android:layout_alignTop="@+id/text_value"
|
||||||
|
android:layout_toEndOf="@+id/text_value"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
11
Source/Android/app/src/main/res/layout/fragment_settings.xml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/list_settings"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
39
Source/Android/app/src/main/res/layout/list_item_setting.xml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="72dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:focusable="true"
|
||||||
|
android:clickable="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
style="@style/TextAppearance.AppCompat.Headline"
|
||||||
|
tools:text="Setting Name"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_marginStart="@dimen/spacing_large"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
|
android:layout_marginTop="@dimen/spacing_large"
|
||||||
|
android:id="@+id/text_setting_name"
|
||||||
|
android:textSize="16sp"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="@string/overclock_enable_description"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_marginStart="@dimen/spacing_large"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
|
android:layout_marginBottom="@dimen/spacing_large"
|
||||||
|
android:layout_marginTop="@dimen/spacing_small"
|
||||||
|
android:id="@+id/text_setting_description"
|
||||||
|
android:layout_below="@+id/text_setting_name"
|
||||||
|
android:layout_alignStart="@+id/text_setting_name"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:minHeight="72dp"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:focusable="true"
|
||||||
|
android:clickable="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_setting_name"
|
||||||
|
style="@style/TextAppearance.AppCompat.Headline"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
|
android:layout_marginStart="@dimen/spacing_large"
|
||||||
|
android:layout_marginTop="@dimen/spacing_large"
|
||||||
|
android:layout_toStartOf="@+id/checkbox"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:text="@string/overclock_enable"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_setting_description"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentStart="true"
|
||||||
|
android:layout_alignStart="@+id/text_setting_name"
|
||||||
|
android:layout_below="@+id/text_setting_name"
|
||||||
|
android:layout_marginBottom="@dimen/spacing_large"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
|
android:layout_marginStart="@dimen/spacing_large"
|
||||||
|
android:layout_marginTop="@dimen/spacing_small"
|
||||||
|
android:layout_toStartOf="@+id/checkbox"
|
||||||
|
tools:text="@string/overclock_enable_description"/>
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/checkbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginEnd="@dimen/spacing_large"
|
||||||
|
android:focusable="false"
|
||||||
|
android:clickable="false"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/text_header_name"
|
||||||
|
tools:text="CPU Settings"
|
||||||
|
android:layout_marginStart="@dimen/spacing_large"
|
||||||
|
android:layout_marginBottom="@dimen/spacing_small"
|
||||||
|
android:textColor="?android:colorAccent"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_gravity="left|bottom"/>
|
||||||
|
|
||||||
|
</FrameLayout>
|
@ -1,23 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:weightSum="1"
|
|
||||||
android:gravity="center_horizontal">
|
|
||||||
|
|
||||||
<SeekBar
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:id="@+id/sliderSeekBar"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
tools:text="Sample Text"
|
|
||||||
android:id="@+id/sliderTextView"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
@ -7,9 +7,14 @@
|
|||||||
android:icon="@drawable/ic_refresh"
|
android:icon="@drawable/ic_refresh"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/menu_settings"
|
android:id="@+id/menu_settings_core"
|
||||||
android:title="@string/grid_menu_settings"
|
android:title="@string/grid_menu_core_settings"
|
||||||
android:icon="@drawable/ic_settings"
|
android:icon="@drawable/ic_settings_core"
|
||||||
|
app:showAsAction="ifRoom"/>
|
||||||
|
<item
|
||||||
|
android:id="@+id/menu_settings_video"
|
||||||
|
android:title="@string/grid_menu_video_settings"
|
||||||
|
android:icon="@drawable/ic_settings_graphics"
|
||||||
app:showAsAction="ifRoom"/>
|
app:showAsAction="ifRoom"/>
|
||||||
|
|
||||||
</menu>
|
</menu>
|
@ -9,77 +9,49 @@
|
|||||||
<item>@string/jit64_recompiler</item>
|
<item>@string/jit64_recompiler</item>
|
||||||
<item>@string/jitil_recompiler</item>
|
<item>@string/jitil_recompiler</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="emuCoreValuesX86_64" translatable="false">
|
<integer-array name="emuCoreValuesX86_64" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- CPU core selection - ARM -->
|
<!-- CPU core selection - ARM -->
|
||||||
<string-array name="emuCoreEntriesARM" translatable="false">
|
<string-array name="emuCoreEntriesARM" translatable="false">
|
||||||
<item>@string/interpreter</item>
|
<item>@string/interpreter</item>
|
||||||
<item>@string/jit_arm_recompiler</item>
|
<item>@string/jit_arm_recompiler</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="emuCoreValuesARM" translatable="false">
|
<integer-array name="emuCoreValuesARM" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- CPU core selection - ARM64 -->
|
<!-- CPU core selection - ARM64 -->
|
||||||
<string-array name="emuCoreEntriesARM64" translatable="false">
|
<string-array name="emuCoreEntriesARM64" translatable="false">
|
||||||
<item>@string/interpreter</item>
|
<item>@string/interpreter</item>
|
||||||
<item>@string/jit_arm64_recompiler</item>
|
<item>@string/jit_arm64_recompiler</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="emuCoreValuesARM64" translatable="false">
|
<integer-array name="emuCoreValuesARM64" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- CPU core selection - Other -->
|
<!-- CPU core selection - Other -->
|
||||||
<string-array name="emuCoreEntriesOther" translatable="false">
|
<string-array name="emuCoreEntriesOther" translatable="false">
|
||||||
<item>@string/interpreter</item>
|
<item>@string/interpreter</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="emuCoreValuesOther" translatable="false">
|
<integer-array name="emuCoreValuesOther" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- New UI CPU Core selection - Default -->
|
<!-- New UI CPU Core selection - Default -->
|
||||||
<string-array name="string_emu_cores" translatable="false">
|
<string-array name="string_emu_cores" translatable="false">
|
||||||
<item>@string/interpreter</item>
|
<item>@string/interpreter</item>
|
||||||
<item>@string/cached_interpreter</item>
|
<item>@string/cached_interpreter</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="int_emu_cores" translatable="false">
|
<integer-array name="int_emu_cores" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>5</item>
|
<item>5</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Video Backend Selection - Supports OpenGL ES 3 -->
|
|
||||||
<string-array name="videoBackendEntriesGLES3" translatable="false">
|
|
||||||
<item>@string/software_renderer</item>
|
|
||||||
<item>@string/opengl_es3</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="videoBackendValuesGLES3" translatable="false">
|
|
||||||
<item>Software Renderer</item>
|
|
||||||
<item>OGL</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<!-- Video Backend Selection - Supports desktop OpenGL -->
|
|
||||||
<string-array name="videoBackendEntriesGL" translatable="false">
|
|
||||||
<item>@string/software_renderer</item>
|
|
||||||
<item>@string/opengl</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="videoBackendValuesGL" translatable="false">
|
|
||||||
<item>Software Renderer</item>
|
|
||||||
<item>OGL</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<!-- Video Backend Selection - No OpenGL ES 3 support -->
|
|
||||||
<string-array name="videoBackendEntriesNoGLES3" translatable="false">
|
|
||||||
<item>@string/software_renderer</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="videoBackendValuesNoGLES3" translatable="false">
|
|
||||||
<item>Software Renderer</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<!-- Wiimote extensions -->
|
<!-- Wiimote extensions -->
|
||||||
<string-array name="wiimoteExtEntries" translatable="false">
|
<string-array name="wiimoteExtEntries" translatable="false">
|
||||||
@ -99,57 +71,17 @@
|
|||||||
<item>Turntable</item>
|
<item>Turntable</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<!-- EFB Copy Method Preference -->
|
|
||||||
<string-array name="efbCopyMethodEntries" translatable="false">
|
|
||||||
<item>@string/disabled</item>
|
|
||||||
<item>@string/efb_copy_texture</item>
|
|
||||||
<item>@string/efb_copy_ram_uncached</item>
|
|
||||||
<item>@string/efb_copy_ram_cached</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="efbCopyMethodValues" translatable="false">
|
|
||||||
<item>Off</item>
|
|
||||||
<item>Texture</item>
|
|
||||||
<item>RAM (cached)</item>
|
|
||||||
<item>RAM (uncached)</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<!-- Texture Cache Accuracy Preference -->
|
<!-- Texture Cache Accuracy Preference -->
|
||||||
<string-array name="textureCacheAccuracyEntries" translatable="false">
|
<string-array name="textureCacheAccuracyEntries" translatable="false">
|
||||||
<item>@string/texture_cache_accuracy_low</item>
|
<item>@string/texture_cache_accuracy_low</item>
|
||||||
<item>@string/texture_cache_accuracy_medium</item>
|
<item>@string/texture_cache_accuracy_medium</item>
|
||||||
<item>@string/texture_cache_accuracy_high</item>
|
<item>@string/texture_cache_accuracy_high</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="textureCacheAccuracyValues" translatable="false">
|
<integer-array name="textureCacheAccuracyValues" translatable="false">
|
||||||
<item>128</item>
|
<item>128</item>
|
||||||
<item>512</item>
|
<item>512</item>
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Analog Modifier ranges -->
|
|
||||||
<string-array name="analogRangesEntries" translatable="false">
|
|
||||||
<item>100</item>
|
|
||||||
<item>90</item>
|
|
||||||
<item>80</item>
|
|
||||||
<item>70</item>
|
|
||||||
<item>60</item>
|
|
||||||
<item>50</item>
|
|
||||||
<item>40</item>
|
|
||||||
<item>30</item>
|
|
||||||
<item>20</item>
|
|
||||||
<item>10</item>
|
|
||||||
</string-array>
|
|
||||||
<string-array name="analogRangesValues" translatable="false">
|
|
||||||
<item>100,000000</item>
|
|
||||||
<item>90,000000</item>
|
|
||||||
<item>80,000000</item>
|
|
||||||
<item>70,000000</item>
|
|
||||||
<item>60,000000</item>
|
|
||||||
<item>50,000000</item>
|
|
||||||
<item>40,000000</item>
|
|
||||||
<item>30,000000</item>
|
|
||||||
<item>20,000000</item>
|
|
||||||
<item>10,000000</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<!-- External Frame Buffer Preference -->
|
<!-- External Frame Buffer Preference -->
|
||||||
<string-array name="externalFrameBufferEntries" translatable="false">
|
<string-array name="externalFrameBufferEntries" translatable="false">
|
||||||
@ -157,11 +89,11 @@
|
|||||||
<item>@string/external_frame_buffer_virtual</item>
|
<item>@string/external_frame_buffer_virtual</item>
|
||||||
<item>@string/external_frame_buffer_real</item>
|
<item>@string/external_frame_buffer_real</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="externalFrameBufferValues" translatable="false">
|
<integer-array name="externalFrameBufferValues" translatable="false">
|
||||||
<item>Disabled</item>
|
<item>0</item>
|
||||||
<item>Virtual</item>
|
<item>1</item>
|
||||||
<item>Real</item>
|
<item>2</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Internal Resolution Preference -->
|
<!-- Internal Resolution Preference -->
|
||||||
<string-array name="internalResolutionEntries" translatable="false">
|
<string-array name="internalResolutionEntries" translatable="false">
|
||||||
@ -174,7 +106,7 @@
|
|||||||
<item>5x Native (3200x2640)</item>
|
<item>5x Native (3200x2640)</item>
|
||||||
<item>6x Native (3840x3168) for 4K</item>
|
<item>6x Native (3840x3168) for 4K</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="internalResolutionValues" translatable="false">
|
<integer-array name="internalResolutionValues" translatable="false">
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
@ -183,7 +115,7 @@
|
|||||||
<item>7</item>
|
<item>7</item>
|
||||||
<item>8</item>
|
<item>8</item>
|
||||||
<item>9</item>
|
<item>9</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- FSAA Preference -->
|
<!-- FSAA Preference -->
|
||||||
<string-array name="FSAAEntries" translatable="false">
|
<string-array name="FSAAEntries" translatable="false">
|
||||||
@ -191,11 +123,11 @@
|
|||||||
<item>2x</item>
|
<item>2x</item>
|
||||||
<item>4x</item>
|
<item>4x</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="FSAAValues" translatable="false">
|
<integer-array name="FSAAValues" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Anisotropic Filtering Preference -->
|
<!-- Anisotropic Filtering Preference -->
|
||||||
<string-array name="anisotropicFilteringEntries" translatable="false">
|
<string-array name="anisotropicFilteringEntries" translatable="false">
|
||||||
@ -205,13 +137,13 @@
|
|||||||
<item>8x</item>
|
<item>8x</item>
|
||||||
<item>16x</item>
|
<item>16x</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="anisotropicFilteringValues" translatable="false">
|
<integer-array name="anisotropicFilteringValues" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
<item>4</item>
|
<item>4</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Stereoscopy Preference -->
|
<!-- Stereoscopy Preference -->
|
||||||
<string-array name="stereoscopyEntries" translatable="false">
|
<string-array name="stereoscopyEntries" translatable="false">
|
||||||
@ -220,12 +152,12 @@
|
|||||||
<item>Top-and-Bottom</item>
|
<item>Top-and-Bottom</item>
|
||||||
<item>Anaglyph</item>
|
<item>Anaglyph</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="stereoscopyValues" translatable="false">
|
<integer-array name="stereoscopyValues" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<!-- Aspect Ratio Preference -->
|
<!-- Aspect Ratio Preference -->
|
||||||
<string-array name="aspectRatioEntries" translatable="false">
|
<string-array name="aspectRatioEntries" translatable="false">
|
||||||
@ -234,12 +166,12 @@
|
|||||||
<item>Force 4:3</item>
|
<item>Force 4:3</item>
|
||||||
<item>Stretch To Window</item>
|
<item>Stretch To Window</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="aspectRatioValues" translatable="false">
|
<integer-array name="aspectRatioValues" translatable="false">
|
||||||
<item>0</item>
|
<item>0</item>
|
||||||
<item>1</item>
|
<item>1</item>
|
||||||
<item>2</item>
|
<item>2</item>
|
||||||
<item>3</item>
|
<item>3</item>
|
||||||
</string-array>
|
</integer-array>
|
||||||
|
|
||||||
<string-array name="country_names">
|
<string-array name="country_names">
|
||||||
<item>Europe</item>
|
<item>Europe</item>
|
||||||
|
@ -9,4 +9,11 @@
|
|||||||
<dimen name="add_button_margin">16dp</dimen>
|
<dimen name="add_button_margin">16dp</dimen>
|
||||||
|
|
||||||
<dimen name="main_appbar_height">128dp</dimen>
|
<dimen name="main_appbar_height">128dp</dimen>
|
||||||
|
|
||||||
|
<dimen name="spacing_xsmall">2dp</dimen>
|
||||||
|
<dimen name="spacing_small">4dp</dimen>
|
||||||
|
<dimen name="spacing_medium">8dp</dimen>
|
||||||
|
<dimen name="spacing_medlarge">12dp</dimen>
|
||||||
|
<dimen name="spacing_large">16dp</dimen>
|
||||||
|
<dimen name="spacing_xlarge">32dp</dimen>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -286,11 +286,8 @@
|
|||||||
<string name="skip_efb_access_descrip">Ignore any requests from the CPU to read/write to the EFB.</string>
|
<string name="skip_efb_access_descrip">Ignore any requests from the CPU to read/write to the EFB.</string>
|
||||||
<string name="ignore_format_changes">Ignore Format Changes</string>
|
<string name="ignore_format_changes">Ignore Format Changes</string>
|
||||||
<string name="ignore_format_changes_descrip">Ignore any changes to the EFB format.</string>
|
<string name="ignore_format_changes_descrip">Ignore any changes to the EFB format.</string>
|
||||||
<string name="efb_copy_method">EFB Copy Method</string>
|
<string name="efb_copy_method">Store EFB Copies to Texture Only</string>
|
||||||
<string name="efb_copy_method_descrip">Determines how EFB copies will be emulated.</string>
|
<string name="efb_copy_method_descrip">Stores EFB Copies exclusively on the GPU, bypassing system memory. Causes graphical defects in a small number of games. If unsure, leave this checked.</string>
|
||||||
<string name="efb_copy_texture">Texture</string>
|
|
||||||
<string name="efb_copy_ram_uncached">RAM (uncached)</string>
|
|
||||||
<string name="efb_copy_ram_cached">RAM (cached)</string>
|
|
||||||
<string name="texture_cache">Texture Cache</string>
|
<string name="texture_cache">Texture Cache</string>
|
||||||
<string name="texture_cache_accuracy">Texture Cache Accuracy</string>
|
<string name="texture_cache_accuracy">Texture Cache Accuracy</string>
|
||||||
<string name="texture_cache_accuracy_descrip">The safer the selection, the less likely the emulator will be missing any texture updates from RAM.</string>
|
<string name="texture_cache_accuracy_descrip">The safer the selection, the less likely the emulator will be missing any texture updates from RAM.</string>
|
||||||
@ -320,7 +317,8 @@
|
|||||||
|
|
||||||
|
|
||||||
<!-- Game Grid Screen-->
|
<!-- Game Grid Screen-->
|
||||||
<string name="grid_menu_settings">Settings</string>
|
<string name="grid_menu_core_settings">Settings</string>
|
||||||
|
<string name="grid_menu_video_settings">Video Settings</string>
|
||||||
<string name="grid_menu_refresh">Refresh Library</string>
|
<string name="grid_menu_refresh">Refresh Library</string>
|
||||||
|
|
||||||
<!-- Add Directory Screen-->
|
<!-- Add Directory Screen-->
|
||||||
@ -334,6 +332,8 @@
|
|||||||
<string name="preferences_extensions">Extension Bindings</string>
|
<string name="preferences_extensions">Extension Bindings</string>
|
||||||
<string name="preferences_video">Video Settings</string>
|
<string name="preferences_video">Video Settings</string>
|
||||||
<string name="emulation_title">Emulation Activity</string>
|
<string name="emulation_title">Emulation Activity</string>
|
||||||
|
<string name="dialog_seekbar_pos">OK</string>
|
||||||
|
<string name="dialog_seekbar_neg">Cancel</string>
|
||||||
|
|
||||||
<!-- Emulation Menu -->
|
<!-- Emulation Menu -->
|
||||||
<string name="emulation_toggle_input">Toggle Touch Controls</string>
|
<string name="emulation_toggle_input">Toggle Touch Controls</string>
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<!-- Same as above, but use default action bar, and mandate margins. -->
|
<!-- Same as above, but use default action bar, and mandate margins. -->
|
||||||
<style name="DolphinSettingsBase" parent="Theme.AppCompat.Light.NoActionBar">
|
<style name="DolphinSettingsBase" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||||
<item name="colorPrimary">@color/dolphin_blue</item>
|
<item name="colorPrimary">@color/dolphin_blue</item>
|
||||||
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
||||||
</style>
|
</style>
|
||||||
|