From 74f197caedf00df80c411f6cfb299fae5822adba Mon Sep 17 00:00:00 2001
From: JosJuice <josjuice@gmail.com>
Date: Mon, 6 Jul 2020 16:57:49 +0200
Subject: [PATCH 1/3] Android: Expose a proper interface for C++ IniFile class

Replaces the inflexible INI functions in NativeLibrary.
---
 .../dolphinemu/dolphinemu/NativeLibrary.java  |  37 -----
 .../activities/EmulationActivity.java         |  35 +++--
 .../dialogs/GamePropertiesDialog.java         |   9 +-
 .../features/settings/model/Settings.java     |  42 +++---
 .../settings/model/view/FilePicker.java       |   7 +-
 .../features/settings/ui/SettingsAdapter.java |   7 +-
 .../ui/viewholder/FilePickerViewHolder.java   |   9 +-
 .../features/settings/utils/SettingsFile.java |  37 +++--
 .../dolphinemu/model/GameFileCache.java       |   8 +-
 .../dolphinemu/overlay/InputOverlay.java      |  15 ++-
 .../dolphinemu/ui/main/MainActivity.java      |  28 ++--
 .../dolphinemu/dolphinemu/utils/IniFile.java  |  69 ++++++++++
 Source/Android/jni/AndroidCommon/IDCache.cpp  |  51 +++++++
 Source/Android/jni/AndroidCommon/IDCache.h    |   6 +
 Source/Android/jni/CMakeLists.txt             |   1 +
 Source/Android/jni/IniFile.cpp                | 121 +++++++++++++++++
 Source/Android/jni/MainAndroid.cpp            | 127 ------------------
 17 files changed, 360 insertions(+), 249 deletions(-)
 create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java
 create mode 100644 Source/Android/jni/IniFile.cpp

diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
index 58c5f0e488..8f3a10b8af 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/NativeLibrary.java
@@ -274,43 +274,6 @@ public final class NativeLibrary
   // Angle is in radians and should be non-negative
   public static native double GetInputRadiusAtAngle(int emu_pad_id, int stick, double angle);
 
-  public static native void NewGameIniFile();
-
-  public static native void LoadGameIniFile(String gameId);
-
-  public static native void SaveGameIniFile(String gameId);
-
-  public static native String GetUserSetting(String gameID, String Section, String Key);
-
-  public static native void SetUserSetting(String gameID, String Section, String Key, String Value);
-
-  public static native void SetProfileSetting(String profile, String Section, String Key,
-          String Value);
-
-  public static native void InitGameIni(String gameID);
-
-  /**
-   * Gets a value from a key in the given ini-based config file.
-   *
-   * @param configFile The ini-based config file to get the value from.
-   * @param Section    The section key that the actual key is in.
-   * @param Key        The key to get the value from.
-   * @param Default    The value to return in the event the given key doesn't exist.
-   * @return the value stored at the key, or a default value if it doesn't exist.
-   */
-  public static native String GetConfig(String configFile, String Section, String Key,
-          String Default);
-
-  /**
-   * Sets a value to a key in the given ini config file.
-   *
-   * @param configFile The ini-based config file to add the value to.
-   * @param Section    The section key for the ini key
-   * @param Key        The actual ini key to set.
-   * @param Value      The string to set the ini key to.
-   */
-  public static native void SetConfig(String configFile, String Section, String Key, String Value);
-
   /**
    * Gets the Dolphin version string.
    *
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index 1faa1bff43..272ec2d233 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -47,10 +47,12 @@ import org.dolphinemu.dolphinemu.ui.main.TvMainActivity;
 import org.dolphinemu.dolphinemu.ui.platform.Platform;
 import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper;
 import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 import org.dolphinemu.dolphinemu.utils.MotionListener;
 import org.dolphinemu.dolphinemu.utils.Rumble;
 import org.dolphinemu.dolphinemu.utils.TvUtil;
 
+import java.io.File;
 import java.lang.annotation.Retention;
 import java.util.List;
 
@@ -962,10 +964,14 @@ public final class EmulationActivity extends AppCompatActivity
             (dialog, indexSelected) ->
             {
               editor.putInt("wiiController", indexSelected);
-              NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "Extension",
+
+              File wiimoteNewFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_WIIMOTE);
+              IniFile wiimoteNewIni = new IniFile(wiimoteNewFile);
+              wiimoteNewIni.setString("Wiimote1", "Extension",
                       getResources().getStringArray(R.array.controllersValues)[indexSelected]);
-              NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1",
-                      "Options/Sideways Wiimote", indexSelected == 2 ? "True" : "False");
+              wiimoteNewIni.setBoolean("Wiimote1", "Options/Sideways Wiimote", indexSelected == 2);
+              wiimoteNewIni.save(wiimoteNewFile);
+
               NativeLibrary.ReloadWiimoteConfig();
             });
     builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) ->
@@ -994,8 +1000,11 @@ public final class EmulationActivity extends AppCompatActivity
               else
                 mMotionListener.disable();
 
-              NativeLibrary.SetConfig("WiimoteNew.ini", "Wiimote1", "IMUIR/Enabled",
-                      indexSelected != 1 ? "True" : "False");
+              File wiimoteNewFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_WIIMOTE);
+              IniFile wiimoteNewIni = new IniFile(wiimoteNewFile);
+              wiimoteNewIni.setBoolean("Wiimote1", "IMUIR/Enabled", indexSelected != 1);
+              wiimoteNewIni.save(wiimoteNewFile);
+
               NativeLibrary.ReloadWiimoteConfig();
             });
     builder.setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> editor.apply());
@@ -1137,15 +1146,15 @@ public final class EmulationActivity extends AppCompatActivity
     builder.setView(view);
     builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
     {
-      NativeLibrary.LoadGameIniFile(mSelectedGameId);
-      NativeLibrary.SetUserSetting(mSelectedGameId, Settings.SECTION_CONTROLS,
-              SettingsFile.KEY_WIIBIND_IR_PITCH, text_slider_value_pitch.getText().toString());
-      NativeLibrary.SetUserSetting(mSelectedGameId, Settings.SECTION_CONTROLS,
-              SettingsFile.KEY_WIIBIND_IR_YAW, text_slider_value_yaw.getText().toString());
-      NativeLibrary.SetUserSetting(mSelectedGameId, Settings.SECTION_CONTROLS,
-              SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET,
+      File file = SettingsFile.getCustomGameSettingsFile(mSelectedGameId);
+      IniFile ini = new IniFile(file);
+      ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH,
+              text_slider_value_pitch.getText().toString());
+      ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW,
+              text_slider_value_yaw.getText().toString());
+      ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET,
               text_slider_value_vertical_offset.getText().toString());
-      NativeLibrary.SaveGameIniFile(mSelectedGameId);
+      ini.save(file);
 
       NativeLibrary.ReloadWiimoteConfig();
 
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java
index e720c20ccd..335fb7aba7 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java
@@ -16,6 +16,7 @@ import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 import org.dolphinemu.dolphinemu.ui.platform.Platform;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
 import org.dolphinemu.dolphinemu.utils.Log;
 
@@ -65,8 +66,12 @@ public class GamePropertiesDialog extends DialogFragment
                           .getSupportFragmentManager(), "game_details");
                   break;
                 case 1:
-                  NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini",
-                          Settings.SECTION_INI_CORE, SettingsFile.KEY_DEFAULT_ISO, path);
+                  File dolphinFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_DOLPHIN);
+                  IniFile dolphinIni = new IniFile(dolphinFile);
+                  dolphinIni.setString(Settings.SECTION_INI_CORE, SettingsFile.KEY_DEFAULT_ISO,
+                          path);
+                  dolphinIni.save(dolphinFile);
+
                   NativeLibrary.ReloadConfig();
                   Toast.makeText(getContext(), "Default ISO set", Toast.LENGTH_SHORT).show();
                   break;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java
index 322b52f894..a2eb5501e6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java
@@ -7,7 +7,9 @@ import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 import org.dolphinemu.dolphinemu.services.GameFileCacheService;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 
+import java.io.File;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
@@ -40,9 +42,9 @@ public class Settings
   public static final String SECTION_CONTROLS = "Controls";
   public static final String SECTION_PROFILE = "Profile";
 
-  private static final String DSP_HLE = "0";
-  private static final String DSP_LLE_RECOMPILER = "1";
-  private static final String DSP_LLE_INTERPRETER = "2";
+  private static final int DSP_HLE = 0;
+  private static final int DSP_LLE_RECOMPILER = 1;
+  private static final int DSP_LLE_INTERPRETER = 2;
 
   public static final String SECTION_ANALYTICS = "Analytics";
 
@@ -195,37 +197,29 @@ public class Settings
 
       if (modifiedSettings.contains(SettingsFile.KEY_DSP_ENGINE))
       {
-        switch (NativeLibrary
-                .GetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_ANDROID,
-                        SettingsFile.KEY_DSP_ENGINE, DSP_HLE))
+        File dolphinFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_DOLPHIN);
+        IniFile dolphinIni = new IniFile(dolphinFile);
+
+        switch (dolphinIni.getInt(Settings.SECTION_INI_ANDROID, SettingsFile.KEY_DSP_ENGINE,
+                DSP_HLE))
         {
           case DSP_HLE:
-            NativeLibrary
-                    .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_CORE,
-                            SettingsFile.KEY_DSP_HLE, "True");
-            NativeLibrary
-                    .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_DSP,
-                            SettingsFile.KEY_DSP_ENABLE_JIT, "True");
+            dolphinIni.setBoolean(Settings.SECTION_INI_CORE, SettingsFile.KEY_DSP_HLE, true);
+            dolphinIni.setBoolean(Settings.SECTION_INI_DSP, SettingsFile.KEY_DSP_ENABLE_JIT, true);
             break;
 
           case DSP_LLE_RECOMPILER:
-            NativeLibrary
-                    .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_CORE,
-                            SettingsFile.KEY_DSP_HLE, "False");
-            NativeLibrary
-                    .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_DSP,
-                            SettingsFile.KEY_DSP_ENABLE_JIT, "True");
+            dolphinIni.setBoolean(Settings.SECTION_INI_CORE, SettingsFile.KEY_DSP_HLE, false);
+            dolphinIni.setBoolean(Settings.SECTION_INI_DSP, SettingsFile.KEY_DSP_ENABLE_JIT, true);
             break;
 
           case DSP_LLE_INTERPRETER:
-            NativeLibrary
-                    .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_CORE,
-                            SettingsFile.KEY_DSP_HLE, "False");
-            NativeLibrary
-                    .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_DSP,
-                            SettingsFile.KEY_DSP_ENABLE_JIT, "False");
+            dolphinIni.setBoolean(Settings.SECTION_INI_CORE, SettingsFile.KEY_DSP_HLE, false);
+            dolphinIni.setBoolean(Settings.SECTION_INI_DSP, SettingsFile.KEY_DSP_ENABLE_JIT, false);
             break;
         }
+
+        dolphinIni.save(dolphinFile);
       }
 
       // Notify the native code of the changes
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java
index 4901795e88..6f9d99b108 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java
@@ -2,6 +2,9 @@ package org.dolphinemu.dolphinemu.features.settings.model.view;
 
 import org.dolphinemu.dolphinemu.features.settings.model.Setting;
 import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
+import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
+
+import java.io.File;
 
 public final class FilePicker extends SettingsItem
 {
@@ -18,9 +21,9 @@ public final class FilePicker extends SettingsItem
     mRequestType = requestType;
   }
 
-  public String getFile()
+  public File getFile()
   {
-    return mFile + ".ini";
+    return SettingsFile.getSettingsFile(mFile);
   }
 
   public String getSelectedValue()
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
index 701cb7219a..bbdeff6227 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
@@ -43,6 +43,7 @@ import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SubmenuViewHold
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
 import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 
 import java.security.InvalidParameterException;
 import java.util.ArrayList;
@@ -319,8 +320,10 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
   {
     FilePicker filePicker = (FilePicker) mClickedItem;
 
-    NativeLibrary.SetConfig(filePicker.getFile(), filePicker.getSection(), filePicker.getKey(),
-            file);
+    IniFile ini = new IniFile(filePicker.getFile());
+    ini.setString(filePicker.getSection(), filePicker.getKey(), file);
+    ini.save(filePicker.getFile());
+
     NativeLibrary.ReloadConfig();
 
     mClickedItem = null;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java
index 681828dc94..01b0f7551b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java
@@ -3,12 +3,12 @@ package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
 import android.view.View;
 import android.widget.TextView;
 
-import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.R;
 import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
 import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 
 public final class FilePickerViewHolder extends SettingViewHolder
 {
@@ -44,9 +44,10 @@ public final class FilePickerViewHolder extends SettingViewHolder
     }
     else
     {
-      mTextSettingDescription.setText(NativeLibrary
-              .GetConfig(mFilePicker.getFile(), item.getSection(), item.getKey(),
-                      mFilePicker.getSelectedValue()));
+      // TODO: Reopening INI files all the time is slow
+      IniFile ini = new IniFile(mFilePicker.getFile());
+      mTextSettingDescription.setText(ini.getString(item.getSection(), item.getKey(),
+              mFilePicker.getSelectedValue()));
     }
   }
 
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
index 090c66caa2..78d7541288 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
@@ -15,6 +15,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView;
 import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
 import org.dolphinemu.dolphinemu.utils.BiMap;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 import org.dolphinemu.dolphinemu.utils.Log;
 
 import java.io.BufferedReader;
@@ -464,7 +465,7 @@ public final class SettingsFile
   {
     Set<String> sortedSections = new TreeSet<>(sections.keySet());
 
-    NativeLibrary.NewGameIniFile();
+    IniFile ini = new IniFile();
     for (String sectionKey : sortedSections)
     {
       SettingSection section = sections.get(sectionKey);
@@ -491,12 +492,12 @@ public final class SettingsFile
         }
         else
         {
-          NativeLibrary.SetUserSetting(gameId, mapSectionNameFromIni(section.getName()),
-                  setting.getKey(), setting.getValueAsString());
+          ini.setString(mapSectionNameFromIni(section.getName()), setting.getKey(),
+                  setting.getValueAsString());
         }
       }
     }
-    NativeLibrary.SaveGameIniFile(gameId);
+    ini.save(getCustomGameSettingsFile(gameId));
   }
 
   /**
@@ -508,31 +509,40 @@ public final class SettingsFile
    * @param padId
    */
   private static void saveCustomWiimoteSetting(final String gameId, final String key,
-          final String value,
-          final String padId)
+          final String value, final String padId)
   {
     String profile = gameId + "_Wii" + padId;
     String wiiConfigPath =
             DirectoryInitialization.getUserDirectory() + "/Config/Profiles/Wiimote/" +
                     profile + ".ini";
-    File wiiProfile = new File(wiiConfigPath);
+    File wiiProfile = getWiiProfile(profile, padId);
     // If it doesn't exist, create it
-    if (!wiiProfile.exists())
+    boolean wiiProfileExists = wiiProfile.exists();
+    if (!wiiProfileExists)
     {
       String defautlWiiProfilePath =
               DirectoryInitialization.getUserDirectory() +
                       "/Config/Profiles/Wiimote/WiimoteProfile.ini";
       DirectoryInitialization.copyFile(defautlWiiProfilePath, wiiConfigPath);
+    }
 
-      NativeLibrary.SetProfileSetting(profile, Settings.SECTION_PROFILE, "Device",
+    IniFile wiiProfileIni = new IniFile(wiiConfigPath);
+
+    if (!wiiProfileExists)
+    {
+      wiiProfileIni.setString(Settings.SECTION_PROFILE, "Device",
               "Android/" + (Integer.parseInt(padId) + 4) + "/Touchscreen");
     }
 
-    NativeLibrary.SetProfileSetting(profile, Settings.SECTION_PROFILE, key, value);
+    wiiProfileIni.setString(Settings.SECTION_PROFILE, key, value);
+    wiiProfileIni.save(wiiConfigPath);
 
     // Enable the profile
-    NativeLibrary.SetUserSetting(gameId, Settings.SECTION_CONTROLS,
+    File gameSettingsFile = SettingsFile.getCustomGameSettingsFile(gameId);
+    IniFile gameSettingsIni = new IniFile(gameSettingsFile);
+    gameSettingsIni.setString(Settings.SECTION_CONTROLS,
             KEY_WIIMOTE_PROFILE + (Integer.parseInt(padId) + 1), profile);
+    gameSettingsIni.save(gameSettingsFile);
   }
 
   private static String mapSectionNameFromIni(String generalSectionName)
@@ -556,7 +566,7 @@ public final class SettingsFile
   }
 
   @NonNull
-  private static File getSettingsFile(String fileName)
+  public static File getSettingsFile(String fileName)
   {
     return new File(
             DirectoryInitialization.getUserDirectory() + "/Config/" + fileName + ".ini");
@@ -578,9 +588,8 @@ public final class SettingsFile
                     gameId + ".ini");
   }
 
-  private static File getCustomGameSettingsFile(String gameId)
+  public static File getCustomGameSettingsFile(String gameId)
   {
-
     return new File(
             DirectoryInitialization.getUserDirectory() + "/GameSettings/" + gameId + ".ini");
   }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java
index 4e38297efa..698f2171cf 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/GameFileCache.java
@@ -7,6 +7,7 @@ import android.preference.PreferenceManager;
 import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 
 import java.io.File;
 import java.util.HashSet;
@@ -82,9 +83,10 @@ public class GameFileCache
    */
   public boolean scanLibrary(Context context)
   {
-    boolean recursiveScan = NativeLibrary
-            .GetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_GENERAL,
-                    SettingsFile.KEY_RECURSIVE_ISO_PATHS, "False").equals("True");
+    IniFile dolphinIni =
+            new IniFile(SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_DOLPHIN));
+    boolean recursiveScan = dolphinIni.getBoolean(Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_RECURSIVE_ISO_PATHS, false);
 
     removeNonExistentGameFolders(context);
 
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java
index dfe431cae7..2093c45bcb 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/overlay/InputOverlay.java
@@ -33,6 +33,7 @@ import org.dolphinemu.dolphinemu.R;
 import org.dolphinemu.dolphinemu.activities.EmulationActivity;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -51,9 +52,9 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
   public static final int OVERLAY_WIIMOTE_CLASSIC = 4;
   public static final int OVERLAY_NONE = 5;
 
-  private static final String DISABLED_GAMECUBE_CONTROLLER = "0";
-  private static final String EMULATED_GAMECUBE_CONTROLLER = "6";
-  private static final String GAMECUBE_ADAPTER = "12";
+  private static final int DISABLED_GAMECUBE_CONTROLLER = 0;
+  private static final int EMULATED_GAMECUBE_CONTROLLER = 6;
+  private static final int GAMECUBE_ADAPTER = 12;
 
   private final Set<InputOverlayDrawableButton> overlayButtons = new HashSet<>();
   private final Set<InputOverlayDrawableDpad> overlayDpads = new HashSet<>();
@@ -703,9 +704,11 @@ public final class InputOverlay extends SurfaceView implements OnTouchListener
       // Add all the enabled overlay items back to the HashSet.
       if (EmulationActivity.isGameCubeGame())
       {
-        switch (NativeLibrary
-                .GetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_CORE,
-                        SettingsFile.KEY_GCPAD_PLAYER_1, EMULATED_GAMECUBE_CONTROLLER))
+        IniFile dolphinIni =
+                new IniFile(SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_DOLPHIN));
+
+        switch (dolphinIni.getInt(Settings.SECTION_INI_CORE, SettingsFile.KEY_GCPAD_PLAYER_1,
+                EMULATED_GAMECUBE_CONTROLLER))
         {
           case DISABLED_GAMECUBE_CONTROLLER:
             if (mIsFirstRun)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
index 5081e58cb1..b6456f41d3 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
@@ -33,9 +33,12 @@ import org.dolphinemu.dolphinemu.services.GameFileCacheService;
 import org.dolphinemu.dolphinemu.ui.platform.Platform;
 import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView;
 import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 import org.dolphinemu.dolphinemu.utils.PermissionsHandler;
 import org.dolphinemu.dolphinemu.utils.StartupHandler;
 
+import java.io.File;
+
 /**
  * The main Activity of the Lollipop style UI. Manages several PlatformGamesFragments, which
  * individually display a grid of available games for each Fragment, in a tabbed layout.
@@ -272,24 +275,19 @@ public final class MainActivity extends AppCompatActivity implements MainView
       public void onTabSelected(@NonNull TabLayout.Tab tab)
       {
         super.onTabSelected(tab);
-        NativeLibrary
-                .SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_ANDROID,
-                        SettingsFile.KEY_LAST_PLATFORM_TAB, Integer.toString(tab.getPosition()));
+
+        File dolphinFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_DOLPHIN);
+        IniFile dolphinIni = new IniFile(dolphinFile);
+        dolphinIni.setInt(Settings.SECTION_INI_ANDROID, SettingsFile.KEY_LAST_PLATFORM_TAB,
+                tab.getPosition());
+        dolphinIni.save(dolphinFile);
       }
     });
 
-    String platformTab = NativeLibrary
-            .GetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_ANDROID,
-                    SettingsFile.KEY_LAST_PLATFORM_TAB, "0");
-
-    try
-    {
-      mViewPager.setCurrentItem(Integer.parseInt(platformTab));
-    }
-    catch (NumberFormatException ex)
-    {
-      mViewPager.setCurrentItem(0);
-    }
+    IniFile dolphinIni =
+            new IniFile(SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_DOLPHIN));
+    mViewPager.setCurrentItem(dolphinIni.getInt(Settings.SECTION_INI_ANDROID,
+            SettingsFile.KEY_LAST_PLATFORM_TAB, 0));
 
     showGames();
     GameFileCacheService.startLoad(this);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java
new file mode 100644
index 0000000000..ecbe7b3122
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java
@@ -0,0 +1,69 @@
+package org.dolphinemu.dolphinemu.utils;
+
+import java.io.File;
+
+// An in-memory copy of an INI file
+public class IniFile
+{
+  // This class is non-static to ensure that the IniFile parent does not get garbage collected
+  // while a section still is accessible. (The finalizer of IniFile deletes the native sections.)
+  public class Section
+  {
+    private long mPointer;  // Do not rename or move without editing the native code
+
+    private Section(long pointer)
+    {
+      mPointer = pointer;
+    }
+  }
+
+  private long mPointer;  // Do not rename or move without editing the native code
+
+  public IniFile()
+  {
+    mPointer = newIniFile();
+  }
+
+  public IniFile(String path)
+  {
+    this();
+    load(path, false);
+  }
+
+  public IniFile(File file)
+  {
+    this();
+    load(file, false);
+  }
+
+  public native boolean load(String path, boolean keepCurrentData);
+
+  public boolean load(File file, boolean keepCurrentData)
+  {
+    return load(file.getPath(), keepCurrentData);
+  }
+
+  public native boolean save(String path);
+
+  public boolean save(File file)
+  {
+    return save(file.getPath());
+  }
+
+  public native String getString(String sectionName, String key, String defaultValue);
+
+  public native boolean getBoolean(String sectionName, String key, boolean defaultValue);
+
+  public native int getInt(String sectionName, String key, int defaultValue);
+
+  public native void setString(String sectionName, String key, String newValue);
+
+  public native void setBoolean(String sectionName, String key, boolean newValue);
+
+  public native void setInt(String sectionName, String key, int newValue);
+
+  @Override
+  public native void finalize();
+
+  private native long newIniFile();
+}
diff --git a/Source/Android/jni/AndroidCommon/IDCache.cpp b/Source/Android/jni/AndroidCommon/IDCache.cpp
index 32160edaee..8383f8ed68 100644
--- a/Source/Android/jni/AndroidCommon/IDCache.cpp
+++ b/Source/Android/jni/AndroidCommon/IDCache.cpp
@@ -30,6 +30,12 @@ static jclass s_linked_hash_map_class;
 static jmethodID s_linked_hash_map_init;
 static jmethodID s_linked_hash_map_put;
 
+static jclass s_ini_file_class;
+static jfieldID s_ini_file_pointer;
+static jclass s_ini_file_section_class;
+static jfieldID s_ini_file_section_pointer;
+static jmethodID s_ini_file_section_constructor;
+
 namespace IDCache
 {
 JNIEnv* GetEnvForThread()
@@ -89,6 +95,7 @@ jmethodID GetAnalyticsValue()
 {
   return s_get_analytics_value;
 }
+
 jclass GetGameFileClass()
 {
   return s_game_file_class;
@@ -129,6 +136,31 @@ jmethodID GetLinkedHashMapPut()
   return s_linked_hash_map_put;
 }
 
+jclass GetIniFileClass()
+{
+  return s_ini_file_class;
+}
+
+jfieldID GetIniFilePointer()
+{
+  return s_ini_file_pointer;
+}
+
+jclass GetIniFileSectionClass()
+{
+  return s_ini_file_section_class;
+}
+
+jfieldID GetIniFileSectionPointer()
+{
+  return s_ini_file_section_pointer;
+}
+
+jmethodID GetIniFileSectionConstructor()
+{
+  return s_ini_file_section_constructor;
+}
+
 }  // namespace IDCache
 
 #ifdef __cplusplus
@@ -150,16 +182,19 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
   s_do_rumble = env->GetStaticMethodID(s_native_library_class, "rumble", "(ID)V");
   s_get_update_touch_pointer =
       env->GetStaticMethodID(s_native_library_class, "updateTouchPointer", "()V");
+  env->DeleteLocalRef(native_library_class);
 
   const jclass game_file_class = env->FindClass("org/dolphinemu/dolphinemu/model/GameFile");
   s_game_file_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_class));
   s_game_file_pointer = env->GetFieldID(game_file_class, "mPointer", "J");
   s_game_file_constructor = env->GetMethodID(game_file_class, "<init>", "(J)V");
+  env->DeleteLocalRef(game_file_class);
 
   const jclass game_file_cache_class =
       env->FindClass("org/dolphinemu/dolphinemu/model/GameFileCache");
   s_game_file_cache_class = reinterpret_cast<jclass>(env->NewGlobalRef(game_file_cache_class));
   s_game_file_cache_pointer = env->GetFieldID(game_file_cache_class, "mPointer", "J");
+  env->DeleteLocalRef(game_file_cache_class);
 
   const jclass analytics_class = env->FindClass("org/dolphinemu/dolphinemu/utils/Analytics");
   s_analytics_class = reinterpret_cast<jclass>(env->NewGlobalRef(analytics_class));
@@ -167,6 +202,20 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
       env->GetStaticMethodID(s_analytics_class, "sendReport", "(Ljava/lang/String;[B)V");
   s_get_analytics_value = env->GetStaticMethodID(s_analytics_class, "getValue",
                                                  "(Ljava/lang/String;)Ljava/lang/String;");
+  env->DeleteLocalRef(analytics_class);
+
+  const jclass ini_file_class = env->FindClass("org/dolphinemu/dolphinemu/utils/IniFile");
+  s_ini_file_class = reinterpret_cast<jclass>(env->NewGlobalRef(ini_file_class));
+  s_ini_file_pointer = env->GetFieldID(ini_file_class, "mPointer", "J");
+  env->DeleteLocalRef(ini_file_class);
+
+  const jclass ini_file_section_class =
+      env->FindClass("org/dolphinemu/dolphinemu/utils/IniFile$Section");
+  s_ini_file_section_class = reinterpret_cast<jclass>(env->NewGlobalRef(ini_file_section_class));
+  s_ini_file_section_pointer = env->GetFieldID(ini_file_section_class, "mPointer", "J");
+  s_ini_file_section_constructor = env->GetMethodID(
+      ini_file_section_class, "<init>", "(Lorg/dolphinemu/dolphinemu/utils/IniFile;J)V");
+  env->DeleteLocalRef(ini_file_section_class);
 
   const jclass map_class = env->FindClass("java/util/LinkedHashMap");
   s_linked_hash_map_class = reinterpret_cast<jclass>(env->NewGlobalRef(map_class));
@@ -188,6 +237,8 @@ void JNI_OnUnload(JavaVM* vm, void* reserved)
   env->DeleteGlobalRef(s_game_file_cache_class);
   env->DeleteGlobalRef(s_analytics_class);
   env->DeleteGlobalRef(s_linked_hash_map_class);
+  env->DeleteGlobalRef(s_ini_file_class);
+  env->DeleteGlobalRef(s_ini_file_section_class);
 }
 
 #ifdef __cplusplus
diff --git a/Source/Android/jni/AndroidCommon/IDCache.h b/Source/Android/jni/AndroidCommon/IDCache.h
index 286009239f..77f49658b8 100644
--- a/Source/Android/jni/AndroidCommon/IDCache.h
+++ b/Source/Android/jni/AndroidCommon/IDCache.h
@@ -32,4 +32,10 @@ jclass GetLinkedHashMapClass();
 jmethodID GetLinkedHashMapInit();
 jmethodID GetLinkedHashMapPut();
 
+jclass GetIniFileClass();
+jfieldID GetIniFilePointer();
+jclass GetIniFileSectionClass();
+jfieldID GetIniFileSectionPointer();
+jmethodID GetIniFileSectionConstructor();
+
 }  // namespace IDCache
diff --git a/Source/Android/jni/CMakeLists.txt b/Source/Android/jni/CMakeLists.txt
index 6279c9e94b..4e806c455b 100644
--- a/Source/Android/jni/CMakeLists.txt
+++ b/Source/Android/jni/CMakeLists.txt
@@ -3,6 +3,7 @@ add_library(main SHARED
   AndroidCommon/IDCache.cpp
   GameList/GameFile.cpp
   GameList/GameFileCache.cpp
+  IniFile.cpp
   MainAndroid.cpp
 )
 
diff --git a/Source/Android/jni/IniFile.cpp b/Source/Android/jni/IniFile.cpp
new file mode 100644
index 0000000000..0237fec4dc
--- /dev/null
+++ b/Source/Android/jni/IniFile.cpp
@@ -0,0 +1,121 @@
+// Copyright 2020 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <jni.h>
+
+#include "Common/IniFile.h"
+#include "jni/AndroidCommon/AndroidCommon.h"
+#include "jni/AndroidCommon/IDCache.h"
+
+static IniFile::Section* GetSectionPointer(JNIEnv* env, jobject obj)
+{
+  return reinterpret_cast<IniFile::Section*>(
+      env->GetLongField(obj, IDCache::GetIniFileSectionPointer()));
+}
+
+static IniFile* GetIniFilePointer(JNIEnv* env, jobject obj)
+{
+  return reinterpret_cast<IniFile*>(env->GetLongField(obj, IDCache::GetIniFilePointer()));
+}
+
+static jobject SectionToJava(JNIEnv* env, jobject ini_file, IniFile::Section* section)
+{
+  if (!section)
+    return nullptr;
+
+  return env->NewObject(IDCache::GetIniFileSectionClass(), IDCache::GetIniFileSectionConstructor(),
+                        ini_file, reinterpret_cast<jlong>(section));
+}
+
+template <typename T>
+static T Get(JNIEnv* env, jobject obj, jstring section_name, jstring key, T default_value)
+{
+  T result;
+  GetIniFilePointer(env, obj)
+      ->GetOrCreateSection(GetJString(env, section_name))
+      ->Get(GetJString(env, key), &result, default_value);
+  return result;
+}
+
+template <typename T>
+static void Set(JNIEnv* env, jobject obj, jstring section_name, jstring key, T new_value)
+{
+  GetIniFilePointer(env, obj)
+      ->GetOrCreateSection(GetJString(env, section_name))
+      ->Set(GetJString(env, key), new_value);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_load(
+    JNIEnv* env, jobject obj, jstring path, jboolean keep_current_data)
+{
+  return static_cast<jboolean>(
+      GetIniFilePointer(env, obj)->Load(GetJString(env, path), keep_current_data));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_save(JNIEnv* env,
+                                                                             jobject obj,
+                                                                             jstring path)
+{
+  return static_cast<jboolean>(GetIniFilePointer(env, obj)->Save(GetJString(env, path)));
+}
+
+JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getString(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key, jstring default_value)
+{
+  return ToJString(env, Get(env, obj, section_name, key, GetJString(env, default_value)));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getBoolean(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key, jboolean default_value)
+{
+  return static_cast<jboolean>(Get(env, obj, section_name, key, static_cast<bool>(default_value)));
+}
+
+JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getInt(JNIEnv* env, jobject obj,
+                                                                           jstring section_name,
+                                                                           jstring key,
+                                                                           jint default_value)
+{
+  return Get(env, obj, section_name, key, default_value);
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_setString(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key, jstring new_value)
+{
+  Set(env, obj, section_name, key, GetJString(env, new_value));
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_setBoolean(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key, jboolean new_value)
+{
+  Set(env, obj, section_name, key, static_cast<bool>(new_value));
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_setInt(JNIEnv* env, jobject obj,
+                                                                           jstring section_name,
+                                                                           jstring key,
+                                                                           jint new_value)
+{
+  Set(env, obj, section_name, key, new_value);
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_finalize(JNIEnv* env,
+                                                                             jobject obj)
+{
+  delete GetIniFilePointer(env, obj);
+}
+
+JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_newIniFile(JNIEnv* env,
+                                                                                jobject obj)
+{
+  return reinterpret_cast<jlong>(new IniFile);
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/Source/Android/jni/MainAndroid.cpp b/Source/Android/jni/MainAndroid.cpp
index 8393fe53d8..0732987a9d 100644
--- a/Source/Android/jni/MainAndroid.cpp
+++ b/Source/Android/jni/MainAndroid.cpp
@@ -213,10 +213,6 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenSh
 JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_eglBindAPI(JNIEnv* env,
                                                                                jobject obj,
                                                                                jint api);
-JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(
-    JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jDefault);
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(
-    JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jValue);
 JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetFilename(JNIEnv* env,
                                                                                 jobject obj,
                                                                                 jstring jFile);
@@ -355,129 +351,6 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_eglBindAPI(J
   eglBindAPI(api);
 }
 
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_InitGameIni(JNIEnv* env,
-                                                                                jobject obj,
-                                                                                jstring jGameID)
-{
-  // Initialize an empty INI file
-  IniFile ini;
-  std::string gameid = GetJString(env, jGameID);
-
-  __android_log_print(ANDROID_LOG_DEBUG, "InitGameIni", "Initializing base game config file");
-  ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini");
-}
-
-JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserSetting(
-    JNIEnv* env, jobject obj, jstring jGameID, jstring jSection, jstring jKey)
-{
-  IniFile ini;
-  std::string gameid = GetJString(env, jGameID);
-  std::string section = GetJString(env, jSection);
-  std::string key = GetJString(env, jKey);
-
-  ini = SConfig::LoadGameIni(gameid, 0);
-  std::string value;
-
-  ini.GetOrCreateSection(section)->Get(key, &value, "-1");
-
-  return ToJString(env, value);
-}
-
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_NewGameIniFile(JNIEnv* env,
-                                                                                   jobject obj)
-{
-  s_ini = IniFile();
-}
-
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadGameIniFile(JNIEnv* env,
-                                                                                    jobject obj,
-                                                                                    jstring jGameID)
-{
-  std::string gameid = GetJString(env, jGameID);
-  s_ini.Load(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini");
-}
-
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveGameIniFile(JNIEnv* env,
-                                                                                    jobject obj,
-                                                                                    jstring jGameID)
-{
-  std::string gameid = GetJString(env, jGameID);
-  s_ini.Save(File::GetUserPath(D_GAMESETTINGS_IDX) + gameid + ".ini");
-}
-
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserSetting(
-    JNIEnv* env, jobject obj, jstring jGameID, jstring jSection, jstring jKey, jstring jValue)
-{
-  std::string gameid = GetJString(env, jGameID);
-  std::string section = GetJString(env, jSection);
-  std::string key = GetJString(env, jKey);
-  std::string val = GetJString(env, jValue);
-
-  if (val != "-1")
-  {
-    s_ini.GetOrCreateSection(section)->Set(key, val);
-  }
-  else
-  {
-    s_ini.GetOrCreateSection(section)->Delete(key);
-  }
-}
-
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfileSetting(
-    JNIEnv* env, jobject obj, jstring jProfile, jstring jSection, jstring jKey, jstring jValue)
-{
-  IniFile ini;
-  std::string profile = GetJString(env, jProfile);
-  std::string section = GetJString(env, jSection);
-  std::string key = GetJString(env, jKey);
-  std::string val = GetJString(env, jValue);
-
-  ini.Load(File::GetUserPath(D_CONFIG_IDX) + "Profiles/Wiimote/" + profile + ".ini");
-
-  if (val != "-1")
-  {
-    ini.GetOrCreateSection(section)->Set(key, val);
-  }
-  else
-  {
-    ini.GetOrCreateSection(section)->Delete(key);
-  }
-
-  ini.Save(File::GetUserPath(D_CONFIG_IDX) + "Profiles/Wiimote/" + profile + ".ini");
-}
-
-JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(
-    JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jDefault)
-{
-  IniFile ini;
-  std::string file = GetJString(env, jFile);
-  std::string section = GetJString(env, jSection);
-  std::string key = GetJString(env, jKey);
-  std::string defaultValue = GetJString(env, jDefault);
-
-  ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file));
-  std::string value;
-
-  ini.GetOrCreateSection(section)->Get(key, &value, defaultValue);
-
-  return ToJString(env, value);
-}
-
-JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(
-    JNIEnv* env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jValue)
-{
-  IniFile ini;
-  std::string file = GetJString(env, jFile);
-  std::string section = GetJString(env, jSection);
-  std::string key = GetJString(env, jKey);
-  std::string value = GetJString(env, jValue);
-
-  ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file));
-
-  ini.GetOrCreateSection(section)->Set(key, value);
-  ini.Save(File::GetUserPath(D_CONFIG_IDX) + std::string(file));
-}
-
 JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv* env,
                                                                               jobject obj,
                                                                               jint slot,

From c6a308380c1f73cf9c707ec2223ee9c8b6ac75d3 Mon Sep 17 00:00:00 2001
From: JosJuice <josjuice@gmail.com>
Date: Tue, 7 Jul 2020 12:26:38 +0200
Subject: [PATCH 2/3] Android: Replace Java INI parser with C++ INI parser

Fixes https://bugs.dolphin-emu.org/issues/12096.
---
 .../activities/EmulationActivity.java         |    7 +-
 .../dolphinemu/dialogs/MotionAlertDialog.java |   11 +-
 .../settings/model/BooleanSetting.java        |   28 -
 .../features/settings/model/FloatSetting.java |   28 -
 .../features/settings/model/IntSetting.java   |   44 -
 .../features/settings/model/Setting.java      |   46 -
 .../settings/model/SettingSection.java        |   63 -
 .../features/settings/model/Settings.java     |  134 +-
 .../settings/model/StringSetting.java         |   28 -
 .../settings/model/view/CheckBoxSetting.java  |   54 +-
 .../settings/model/view/FilePicker.java       |   31 +-
 .../model/view/FloatSliderSetting.java        |   39 +
 .../settings/model/view/HeaderSetting.java    |    6 +-
 .../model/view/InputBindingSetting.java       |   54 +-
 .../settings/model/view/IntSliderSetting.java |   25 +
 .../model/view/RumbleBindingSetting.java      |   38 +-
 .../settings/model/view/SettingsItem.java     |   73 +-
 .../model/view/SingleChoiceSetting.java       |   49 +-
 ...ingleChoiceSettingDynamicDescriptions.java |   57 +-
 .../settings/model/view/SliderSetting.java    |  103 +-
 .../model/view/StringSingleChoiceSetting.java |   65 +-
 .../settings/model/view/SubmenuSetting.java   |    5 +-
 .../features/settings/ui/SettingsAdapter.java |  158 +-
 .../settings/ui/SettingsFragment.java         |    6 +-
 .../ui/SettingsFragmentPresenter.java         | 1781 +++++++----------
 .../settings/ui/SettingsFragmentView.java     |   11 +-
 .../viewholder/CheckBoxSettingViewHolder.java |    2 +-
 .../ui/viewholder/FilePickerViewHolder.java   |    5 +-
 .../ui/viewholder/SingleChoiceViewHolder.java |    6 +-
 .../ui/viewholder/SliderViewHolder.java       |    4 +-
 .../features/settings/utils/SettingsFile.java |  339 +---
 .../dolphinemu/fragments/MenuFragment.java    |   10 +-
 .../dolphinemu/dolphinemu/utils/IniFile.java  |   41 +
 .../dolphinemu/dolphinemu/utils/Rumble.java   |   12 +-
 Source/Android/jni/IniFile.cpp                |  128 ++
 35 files changed, 1238 insertions(+), 2253 deletions(-)
 delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java
 delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/FloatSetting.java
 delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java
 delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Setting.java
 delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/SettingSection.java
 delete mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java
 create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java
 create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/IntSliderSetting.java

diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index 272ec2d233..3ffd0e93ec 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -32,7 +32,6 @@ import android.widget.Toast;
 
 import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.R;
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 import org.dolphinemu.dolphinemu.fragments.EmulationFragment;
@@ -521,10 +520,8 @@ public final class EmulationActivity extends AppCompatActivity
       showUnpauseEmulationButton();
     }
 
-    BooleanSetting enableSaveStates =
-            (BooleanSetting) mSettings.getSection(Settings.SECTION_INI_CORE)
-                    .getSetting(SettingsFile.KEY_ENABLE_SAVE_STATES);
-    if (enableSaveStates != null && enableSaveStates.getValue())
+    if (mSettings.getSection(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE)
+            .getBoolean(SettingsFile.KEY_ENABLE_SAVE_STATES, false))
     {
       menu.findItem(R.id.menu_quicksave).setVisible(true);
       menu.findItem(R.id.menu_quickload).setVisible(true);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java
index 29f0d45a6e..39140c4829 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java
@@ -9,6 +9,7 @@ import androidx.annotation.NonNull;
 import androidx.appcompat.app.AlertDialog;
 
 import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
+import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
 import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper;
 import org.dolphinemu.dolphinemu.utils.Log;
 import org.dolphinemu.dolphinemu.utils.TvUtil;
@@ -27,6 +28,7 @@ public final class MotionAlertDialog extends AlertDialog
   private final ArrayList<Float> mPreviousValues = new ArrayList<>();
   private int mPrevDeviceId = 0;
   private boolean mWaitingForEvent = true;
+  private SettingsAdapter mAdapter;
 
   /**
    * Constructor
@@ -34,11 +36,12 @@ public final class MotionAlertDialog extends AlertDialog
    * @param context The current {@link Context}.
    * @param setting The Preference to show this dialog for.
    */
-  public MotionAlertDialog(Context context, InputBindingSetting setting)
+  public MotionAlertDialog(Context context, InputBindingSetting setting, SettingsAdapter adapter)
   {
     super(context);
 
     this.setting = setting;
+    mAdapter = adapter;
   }
 
   public boolean onKeyEvent(int keyCode, KeyEvent event)
@@ -48,7 +51,7 @@ public final class MotionAlertDialog extends AlertDialog
     {
       if (!ControllerMappingHelper.shouldKeyBeIgnored(event.getDevice(), keyCode))
       {
-        setting.onKeyInput(event);
+        setting.onKeyInput(mAdapter.getSettings(), event);
         dismiss();
       }
       // Even if we ignore the key, we still consume it. Thus return true regardless.
@@ -63,7 +66,7 @@ public final class MotionAlertDialog extends AlertDialog
     // Option to clear by long back is only needed on the TV interface
     if (TvUtil.isLeanback(getContext()) && keyCode == KeyEvent.KEYCODE_BACK)
     {
-      setting.clearValue();
+      setting.clearValue(mAdapter.getSettings());
       dismiss();
       return true;
     }
@@ -158,7 +161,7 @@ public final class MotionAlertDialog extends AlertDialog
       if (numMovedAxis == 1)
       {
         mWaitingForEvent = false;
-        setting.onMotionInput(input, lastMovedRange, lastMovedDir);
+        setting.onMotionInput(mAdapter.getSettings(), input, lastMovedRange, lastMovedDir);
         dismiss();
       }
     }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java
deleted file mode 100644
index facf6d8c10..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.dolphinemu.dolphinemu.features.settings.model;
-
-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";
-  }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/FloatSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/FloatSetting.java
deleted file mode 100644
index 53dc837f4f..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/FloatSetting.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.dolphinemu.dolphinemu.features.settings.model;
-
-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);
-  }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java
deleted file mode 100644
index 0ca18cface..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.dolphinemu.dolphinemu.features.settings.model;
-
-import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
-
-public final class IntSetting extends Setting
-{
-  private int mValue;
-  private MenuTag menuTag;
-
-  public IntSetting(String key, String section, int value)
-  {
-    super(key, section);
-    mValue = value;
-  }
-
-  public IntSetting(String key, String section, int value, MenuTag menuTag)
-  {
-    super(key, section);
-    mValue = value;
-    this.menuTag = menuTag;
-  }
-
-  public int getValue()
-  {
-    return mValue;
-  }
-
-  public void setValue(int value)
-  {
-    mValue = value;
-  }
-
-  @Override
-  public String getValueAsString()
-  {
-    return Integer.toString(mValue);
-  }
-
-  public MenuTag getMenuTag()
-  {
-    return menuTag;
-  }
-
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Setting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Setting.java
deleted file mode 100644
index 6dcc49478c..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Setting.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.dolphinemu.dolphinemu.features.settings.model;
-
-/**
- * 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();
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/SettingSection.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/SettingSection.java
deleted file mode 100644
index 7a919a584e..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/SettingSection.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package org.dolphinemu.dolphinemu.features.settings.model;
-
-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 setting The Setting to be inserted.
-   */
-  public void putSetting(Setting setting)
-  {
-    mSettings.put(setting.getKey(), 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;
-  }
-
-  public void mergeSection(SettingSection settingSection)
-  {
-    for (Setting setting : settingSection.mSettings.values())
-    {
-      putSetting(setting);
-    }
-  }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java
index a2eb5501e6..3bd223425e 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/Settings.java
@@ -48,73 +48,45 @@ public class Settings
 
   public static final String SECTION_ANALYTICS = "Analytics";
 
+  public static final String GAME_SETTINGS_PLACEHOLDER_FILE_NAME = "";
+
   private String gameId;
 
-  private static final Map<String, List<String>> configFileSectionsMap = new HashMap<>();
+  private static final String[] configFiles = new String[]{SettingsFile.FILE_NAME_DOLPHIN,
+          SettingsFile.FILE_NAME_GFX, SettingsFile.FILE_NAME_LOGGER,
+          SettingsFile.FILE_NAME_WIIMOTE};
 
-  static
+  private HashMap<String, IniFile> mIniFiles = new HashMap<>();
+
+  private IniFile getGameSpecificFile()
   {
-    configFileSectionsMap.put(SettingsFile.FILE_NAME_DOLPHIN,
-            Arrays
-                    .asList(SECTION_INI_ANDROID, SECTION_INI_GENERAL, SECTION_INI_CORE,
-                            SECTION_INI_INTERFACE,
-                            SECTION_INI_DSP, SECTION_BINDINGS, SECTION_ANALYTICS, SECTION_DEBUG));
-    configFileSectionsMap.put(SettingsFile.FILE_NAME_GFX,
-            Arrays.asList(SECTION_GFX_SETTINGS, SECTION_GFX_ENHANCEMENTS, SECTION_GFX_HACKS,
-                    SECTION_STEREOSCOPY));
-    configFileSectionsMap.put(SettingsFile.FILE_NAME_LOGGER,
-            Arrays.asList(SECTION_LOGGER_LOGS, SECTION_LOGGER_OPTIONS));
-    configFileSectionsMap.put(SettingsFile.FILE_NAME_WIIMOTE,
-            Arrays.asList(SECTION_WIIMOTE + 1, SECTION_WIIMOTE + 2, SECTION_WIIMOTE + 3,
-                    SECTION_WIIMOTE + 4));
+    if (TextUtils.isEmpty(gameId) || mIniFiles.size() != 1)
+      throw new IllegalStateException();
+
+    return mIniFiles.get(GAME_SETTINGS_PLACEHOLDER_FILE_NAME);
   }
 
-  /**
-   * A HashMap<String, SettingSection> that constructs a new SettingSection instead of returning null
-   * when getting a key not already in the map
-   */
-  public static final class SettingsSectionMap extends HashMap<String, SettingSection>
+  public IniFile.Section getSection(String fileName, String sectionName)
   {
-    @Override
-    public SettingSection get(Object key)
+    if (TextUtils.isEmpty(gameId))
     {
-      if (!(key instanceof String))
-      {
-        return null;
-      }
-
-      String stringKey = (String) key;
-
-      if (!super.containsKey(stringKey))
-      {
-        SettingSection section = new SettingSection(stringKey);
-        super.put(stringKey, section);
-        return section;
-      }
-      return super.get(key);
+      return mIniFiles.get(fileName).getOrCreateSection(sectionName);
+    }
+    else
+    {
+      return getGameSpecificFile()
+              .getOrCreateSection(SettingsFile.mapSectionNameFromIni(sectionName));
     }
-  }
-
-  private HashMap<String, SettingSection> sections = new Settings.SettingsSectionMap();
-
-  public SettingSection getSection(String sectionName)
-  {
-    return sections.get(sectionName);
   }
 
   public boolean isEmpty()
   {
-    return sections.isEmpty();
-  }
-
-  public HashMap<String, SettingSection> getSections()
-  {
-    return sections;
+    return mIniFiles.isEmpty();
   }
 
   public void loadSettings(SettingsActivityView view)
   {
-    sections = new Settings.SettingsSectionMap();
+    mIniFiles = new HashMap<>();
 
     if (TextUtils.isEmpty(gameId))
     {
@@ -128,46 +100,24 @@ public class Settings
 
   private void loadDolphinSettings(SettingsActivityView view)
   {
-    for (Map.Entry<String, List<String>> entry : configFileSectionsMap.entrySet())
+    for (String fileName : configFiles)
     {
-      String fileName = entry.getKey();
-      sections.putAll(SettingsFile.readFile(fileName, view));
+      IniFile ini = new IniFile();
+      SettingsFile.readFile(fileName, ini, view);
+      mIniFiles.put(fileName, ini);
     }
   }
 
-  private void loadGenericGameSettings(String gameId, SettingsActivityView view)
-  {
-    // generic game settings
-    mergeSections(SettingsFile.readGenericGameSettings(gameId, view));
-    mergeSections(SettingsFile.readGenericGameSettingsForAllRegions(gameId, view));
-  }
-
   private void loadCustomGameSettings(String gameId, SettingsActivityView view)
   {
-    // custom game settings
-    mergeSections(SettingsFile.readCustomGameSettings(gameId, view));
+    IniFile ini = new IniFile();
+    SettingsFile.readCustomGameSettings(gameId, ini, view);
+    mIniFiles.put(GAME_SETTINGS_PLACEHOLDER_FILE_NAME, ini);
   }
 
-  public void loadWiimoteProfile(String gameId, String padId)
+  public void loadWiimoteProfile(String gameId, int padId)
   {
-    mergeSections(SettingsFile.readWiimoteProfile(gameId, padId));
-  }
-
-  private void mergeSections(HashMap<String, SettingSection> updatedSections)
-  {
-    for (Map.Entry<String, SettingSection> entry : updatedSections.entrySet())
-    {
-      if (sections.containsKey(entry.getKey()))
-      {
-        SettingSection originalSection = sections.get(entry.getKey());
-        SettingSection updatedSection = entry.getValue();
-        originalSection.mergeSection(updatedSection);
-      }
-      else
-      {
-        sections.put(entry.getKey(), entry.getValue());
-      }
-    }
+    SettingsFile.readWiimoteProfile(gameId, getGameSpecificFile(), padId);
   }
 
   public void loadSettings(String gameId, SettingsActivityView view)
@@ -182,17 +132,9 @@ public class Settings
     {
       view.showToastMessage("Saved settings to INI files");
 
-      for (Map.Entry<String, List<String>> entry : configFileSectionsMap.entrySet())
+      for (Map.Entry<String, IniFile> entry : mIniFiles.entrySet())
       {
-        String fileName = entry.getKey();
-        List<String> sectionNames = entry.getValue();
-        TreeMap<String, SettingSection> iniSections = new TreeMap<>();
-        for (String section : sectionNames)
-        {
-          iniSections.put(section, sections.get(section));
-        }
-
-        SettingsFile.saveFile(fileName, iniSections, view);
+        SettingsFile.saveFile(entry.getKey(), entry.getValue(), view);
       }
 
       if (modifiedSettings.contains(SettingsFile.KEY_DSP_ENGINE))
@@ -240,13 +182,16 @@ public class Settings
     {
       // custom game settings
       view.showToastMessage("Saved settings for " + gameId);
-      SettingsFile.saveCustomGameSettings(gameId, sections);
+      SettingsFile.saveCustomGameSettings(gameId, getGameSpecificFile());
     }
   }
 
   public void clearSettings()
   {
-    sections.clear();
+    for (String fileName : mIniFiles.keySet())
+    {
+      mIniFiles.put(fileName, new IniFile());
+    }
   }
 
   public boolean gameIniContainsJunk()
@@ -272,7 +217,6 @@ public class Settings
     if (TextUtils.isEmpty(gameId))
       return false;
 
-    SettingSection interfaceSection = sections.get("Interface");
-    return interfaceSection != null && interfaceSection.getSetting("ThemeName") != null;
+    return getSection(SettingsFile.FILE_NAME_DOLPHIN, SECTION_INI_INTERFACE).exists("ThemeName");
   }
 }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java
deleted file mode 100644
index c5c0e3b372..0000000000
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/StringSetting.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.dolphinemu.dolphinemu.features.settings.model;
-
-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;
-  }
-}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java
index 38af32be9d..a322f863a4 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java
@@ -1,51 +1,39 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
+import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 
 public final class CheckBoxSetting extends SettingsItem
 {
   private boolean mDefaultValue;
 
-  public CheckBoxSetting(String key, String section, int titleId, int descriptionId,
-          boolean defaultValue, Setting setting)
+  public CheckBoxSetting(String file, String section, String key, int titleId, int descriptionId,
+          boolean defaultValue)
   {
-    super(key, section, setting, titleId, descriptionId);
+    super(file, section, key, titleId, descriptionId);
     mDefaultValue = defaultValue;
   }
 
-  public boolean isChecked()
+  public boolean isChecked(Settings settings)
   {
-    if (getSetting() == null || !(getSetting() instanceof BooleanSetting))
-    {
-      return mDefaultValue;
-    }
-
-    BooleanSetting setting = (BooleanSetting) getSetting();
-    return setting.getValue();
+    return invertIfNeeded(settings.getSection(getFile(), getSection())
+            .getBoolean(getKey(), invertIfNeeded(mDefaultValue)));
   }
 
-  /**
-   * 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)
+  public void setChecked(Settings settings, boolean checked)
   {
-    if (getSetting() == null || !(getSetting() instanceof BooleanSetting))
-    {
-      BooleanSetting setting = new BooleanSetting(getKey(), getSection(), checked);
-      setSetting(setting);
-      return setting;
-    }
-    else
-    {
-      BooleanSetting setting = (BooleanSetting) getSetting();
-      setting.setValue(checked);
-      return null;
-    }
+    settings.getSection(getFile(), getSection()).setBoolean(getKey(), invertIfNeeded(checked));
+  }
+
+  private boolean invertIfNeeded(boolean x)
+  {
+    return isInverted() ? !x : x;
+  }
+
+  private boolean isInverted()
+  {
+    return getKey().equals(SettingsFile.KEY_SKIP_EFB) ||
+            getKey().equals(SettingsFile.KEY_IGNORE_FORMAT);
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java
index 6f9d99b108..15b69c5e0d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FilePicker.java
@@ -1,42 +1,23 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
-import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
-
-import java.io.File;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 
 public final class FilePicker extends SettingsItem
 {
-  private String mFile;
   private String mDefaultValue;
   private int mRequestType;
 
-  public FilePicker(String file, String key, String section, int titleId, int descriptionId,
-          String defaultVault, int requestType, Setting setting)
+  public FilePicker(String file, String section, String key, int titleId, int descriptionId,
+          String defaultVault, int requestType)
   {
-    super(key, section, setting, titleId, descriptionId);
-    mFile = file;
+    super(file, section, key, titleId, descriptionId);
     mDefaultValue = defaultVault;
     mRequestType = requestType;
   }
 
-  public File getFile()
+  public String getSelectedValue(Settings settings)
   {
-    return SettingsFile.getSettingsFile(mFile);
-  }
-
-  public String getSelectedValue()
-  {
-    if (getSetting() == null || !(getSetting() instanceof StringSetting))
-    {
-      return mDefaultValue;
-    }
-    else
-    {
-      StringSetting setting = (StringSetting) getSetting();
-      return setting.getValue();
-    }
+    return settings.getSection(getFile(), getSection()).getString(getKey(), mDefaultValue);
   }
 
   public int getRequestType()
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java
new file mode 100644
index 0000000000..39ce129822
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java
@@ -0,0 +1,39 @@
+package org.dolphinemu.dolphinemu.features.settings.model.view;
+
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
+import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
+
+public final class FloatSliderSetting extends SliderSetting
+{
+  private float mDefaultValue;
+
+  public FloatSliderSetting(String file, String section, String key, int titleId, int descriptionId,
+          int max, String units, float defaultValue)
+  {
+    super(file, section, key, titleId, descriptionId, max, units);
+    mDefaultValue = defaultValue;
+
+    if (isPercentSetting())
+      mDefaultValue /= 100;
+  }
+
+  public int getSelectedValue(Settings settings)
+  {
+    float value = settings.getSection(getFile(), getSection()).getFloat(getKey(), mDefaultValue);
+    return Math.round(isPercentSetting() ? value * 100 : value);
+  }
+
+  public void setSelectedValue(Settings settings, float selection)
+  {
+    if (isPercentSetting())
+      selection /= 100;
+
+    settings.getSection(getFile(), getSection()).setFloat(getKey(), selection);
+  }
+
+  private boolean isPercentSetting()
+  {
+    return getKey().equals(SettingsFile.KEY_OVERCLOCK_PERCENT)
+            || getKey().equals(SettingsFile.KEY_SPEED_LIMIT);
+  }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/HeaderSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/HeaderSetting.java
index f0387a0515..7948d5e67a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/HeaderSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/HeaderSetting.java
@@ -1,12 +1,10 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-
 public final class HeaderSetting extends SettingsItem
 {
-  public HeaderSetting(String key, Setting setting, int titleId, int descriptionId)
+  public HeaderSetting(String key, int titleId, int descriptionId)
   {
-    super(key, null, setting, titleId, descriptionId);
+    super(null, null, key, titleId, descriptionId);
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InputBindingSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InputBindingSetting.java
index b762539d1a..d1941ab5d0 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InputBindingSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InputBindingSetting.java
@@ -6,29 +6,21 @@ import android.view.InputDevice;
 import android.view.KeyEvent;
 
 import org.dolphinemu.dolphinemu.DolphinApplication;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 
 public class InputBindingSetting extends SettingsItem
 {
   private String gameId;
 
-  public InputBindingSetting(String key, String section, int titleId, Setting setting,
-          String gameId)
+  public InputBindingSetting(String file, String section, String key, int titleId, String gameId)
   {
-    super(key, section, setting, titleId, 0);
+    super(file, section, key, titleId, 0);
     this.gameId = gameId;
   }
 
-  public String getValue()
+  public String getValue(Settings settings)
   {
-    if (getSetting() == null || !(getSetting() instanceof StringSetting))
-    {
-      return "";
-    }
-
-    StringSetting setting = (StringSetting) getSetting();
-    return setting.getValue();
+    return settings.getSection(getFile(), getSection()).getString(getKey(), "");
   }
 
   /**
@@ -37,12 +29,12 @@ public class InputBindingSetting extends SettingsItem
    *
    * @param keyEvent KeyEvent of this key press.
    */
-  public void onKeyInput(KeyEvent keyEvent)
+  public void onKeyInput(Settings settings, KeyEvent keyEvent)
   {
     InputDevice device = keyEvent.getDevice();
     String bindStr = "Device '" + device.getDescriptor() + "'-Button " + keyEvent.getKeyCode();
     String uiString = device.getName() + ": Button " + keyEvent.getKeyCode();
-    setValue(bindStr, uiString);
+    setValue(settings, bindStr, uiString);
   }
 
   /**
@@ -53,23 +45,16 @@ public class InputBindingSetting extends SettingsItem
    * @param motionRange MotionRange of the movement
    * @param axisDir     Either '-' or '+'
    */
-  public void onMotionInput(InputDevice device, InputDevice.MotionRange motionRange,
-          char axisDir)
+  public void onMotionInput(Settings settings, InputDevice device,
+          InputDevice.MotionRange motionRange, char axisDir)
   {
     String bindStr =
             "Device '" + device.getDescriptor() + "'-Axis " + motionRange.getAxis() + axisDir;
     String uiString = device.getName() + ": Axis " + motionRange.getAxis() + axisDir;
-    setValue(bindStr, uiString);
+    setValue(settings, bindStr, uiString);
   }
 
-  /**
-   * Write a value to the backing string. If that string was previously null,
-   * initializes a new one and returns it, so it can be added to the Hashmap.
-   *
-   * @param bind The input that will be bound
-   * @return null if overwritten successfully; otherwise, a newly created StringSetting.
-   */
-  public StringSetting setValue(String bind, String ui)
+  public void setValue(Settings settings, String bind, String ui)
   {
     SharedPreferences
             preferences =
@@ -78,23 +63,12 @@ public class InputBindingSetting extends SettingsItem
     editor.putString(getKey() + gameId, ui);
     editor.apply();
 
-    if (getSetting() == null || !(getSetting() instanceof StringSetting))
-    {
-      StringSetting setting = new StringSetting(getKey(), getSection(), bind);
-      setSetting(setting);
-      return setting;
-    }
-    else
-    {
-      StringSetting setting = (StringSetting) getSetting();
-      setting.setValue(bind);
-      return null;
-    }
+    settings.getSection(getFile(), getSection()).setString(getKey(), bind);
   }
 
-  public void clearValue()
+  public void clearValue(Settings settings)
   {
-    setValue("", "");
+    setValue(settings, "", "");
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/IntSliderSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/IntSliderSetting.java
new file mode 100644
index 0000000000..3455c1dd4a
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/IntSliderSetting.java
@@ -0,0 +1,25 @@
+package org.dolphinemu.dolphinemu.features.settings.model.view;
+
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
+
+public final class IntSliderSetting extends SliderSetting
+{
+  private int mDefaultValue;
+
+  public IntSliderSetting(String file, String section, String key, int titleId, int descriptionId,
+          int max, String units, int defaultValue)
+  {
+    super(file, section, key, titleId, descriptionId, max, units);
+    mDefaultValue = defaultValue;
+  }
+
+  public int getSelectedValue(Settings settings)
+  {
+    return settings.getSection(getFile(), getSection()).getInt(getKey(), mDefaultValue);
+  }
+
+  public void setSelectedValue(Settings settings, int selection)
+  {
+    settings.getSection(getFile(), getSection()).setInt(getKey(), selection);
+  }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/RumbleBindingSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/RumbleBindingSetting.java
index 5d658a7205..fa0bfb95c5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/RumbleBindingSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/RumbleBindingSetting.java
@@ -6,62 +6,46 @@ import android.view.KeyEvent;
 
 import org.dolphinemu.dolphinemu.DolphinApplication;
 import org.dolphinemu.dolphinemu.R;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.utils.Rumble;
 
 public class RumbleBindingSetting extends InputBindingSetting
 {
-
-  public RumbleBindingSetting(String key, String section, int titleId, Setting setting,
-          String gameId)
+  public RumbleBindingSetting(String file, String section, String key, int titleId, String gameId)
   {
-    super(key, section, titleId, setting, gameId);
-  }
-
-  @Override
-  public String getValue()
-  {
-    if (getSetting() == null || !(getSetting() instanceof StringSetting))
-    {
-      return "";
-    }
-
-    StringSetting setting = (StringSetting) getSetting();
-    return setting.getValue();
+    super(file, section, key, titleId, gameId);
   }
 
   /**
    * Just need the device when saving rumble.
    */
   @Override
-  public void onKeyInput(KeyEvent keyEvent)
+  public void onKeyInput(Settings settings, KeyEvent keyEvent)
   {
-    saveRumble(keyEvent.getDevice());
+    saveRumble(settings, keyEvent.getDevice());
   }
 
   /**
    * Just need the device when saving rumble.
    */
   @Override
-  public void onMotionInput(InputDevice device,
-          InputDevice.MotionRange motionRange,
-          char axisDir)
+  public void onMotionInput(Settings settings, InputDevice device,
+          InputDevice.MotionRange motionRange, char axisDir)
   {
-    saveRumble(device);
+    saveRumble(settings, device);
   }
 
-  private void saveRumble(InputDevice device)
+  private void saveRumble(Settings settings, InputDevice device)
   {
     Vibrator vibrator = device.getVibrator();
     if (vibrator != null && vibrator.hasVibrator())
     {
-      setValue(device.getDescriptor(), device.getName());
+      setValue(settings, device.getDescriptor(), device.getName());
       Rumble.doRumble(vibrator);
     }
     else
     {
-      setValue("",
+      setValue(settings, "",
               DolphinApplication.getAppContext().getString(R.string.rumble_not_found));
     }
   }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java
index c56293fcdf..0a50a33f31 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SettingsItem.java
@@ -1,14 +1,11 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
-import org.dolphinemu.dolphinemu.features.settings.model.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.)
+ * Most of them correspond to a single line in an INI file, but there are a few with multiple
+ * analogues and a few with none (Headers, for example, do not correspond to anything on disk.)
  */
 public abstract class SettingsItem
 {
@@ -24,36 +21,50 @@ public abstract class SettingsItem
   public static final int TYPE_FILE_PICKER = 9;
   public static final int TYPE_CONFIRM_RUNNABLE = 10;
 
-  private String mKey;
+  private String mFile;
   private String mSection;
-
-  private Setting mSetting;
+  private String mKey;
 
   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.
+   * Base constructor.
    *
-   * @param key           Identifier for the Setting represented by this Item.
+   * @param file          File to which the Setting belongs.
    * @param section       Section to which the Setting belongs.
-   * @param setting       A possibly-null backing Setting, to be modified on UI events.
+   * @param key           Identifier for the Setting represented by this Item.
    * @param nameId        Resource ID for a text string to be displayed as this setting's name.
    * @param descriptionId Resource ID for a text string to be displayed as this setting's description.
    */
 
-  public SettingsItem(String key, String section, Setting setting, int nameId, int descriptionId)
+  public SettingsItem(String file, String section, String key, int nameId, int descriptionId)
   {
-    mKey = key;
+    mFile = file;
     mSection = section;
-    mSetting = setting;
+    mKey = key;
     mNameId = nameId;
     mDescriptionId = descriptionId;
   }
 
   /**
-   * @return The identifier for the backing Setting.
+   * @return The file in which the backing setting belongs.
+   */
+  public String getFile()
+  {
+    return mFile;
+  }
+
+  /**
+   * @return The header under which the backing setting belongs.
+   */
+  public String getSection()
+  {
+    return mSection;
+  }
+
+  /**
+   * @return The identifier for the backing setting.
    */
   public String getKey()
   {
@@ -61,35 +72,7 @@ public abstract class SettingsItem
   }
 
   /**
-   * @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.
+   * @return A resource ID for a text string representing this setting's name.
    */
   public int getNameId()
   {
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSetting.java
index 52c2337ea2..f3a0b3cf7b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSetting.java
@@ -1,7 +1,6 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
 
 public final class SingleChoiceSetting extends SettingsItem
@@ -12,20 +11,20 @@ public final class SingleChoiceSetting extends SettingsItem
   private int mValuesId;
   private MenuTag menuTag;
 
-  public SingleChoiceSetting(String key, String section, int titleId, int descriptionId,
-          int choicesId, int valuesId, int defaultValue, Setting setting, MenuTag menuTag)
+  public SingleChoiceSetting(String file, String section, String key, int titleId,
+          int descriptionId, int choicesId, int valuesId, int defaultValue, MenuTag menuTag)
   {
-    super(key, section, setting, titleId, descriptionId);
+    super(file, section, key, titleId, descriptionId);
     mValuesId = valuesId;
     mChoicesId = choicesId;
     mDefaultValue = defaultValue;
     this.menuTag = menuTag;
   }
 
-  public SingleChoiceSetting(String key, String section, int titleId, int descriptionId,
-          int choicesId, int valuesId, int defaultValue, Setting setting)
+  public SingleChoiceSetting(String file, String section, String key, int titleId,
+          int descriptionId, int choicesId, int valuesId, int defaultValue)
   {
-    this(key, section, titleId, descriptionId, choicesId, valuesId, defaultValue, setting, null);
+    this(file, section, key, titleId, descriptionId, choicesId, valuesId, defaultValue, null);
   }
 
   public int getChoicesId()
@@ -38,17 +37,9 @@ public final class SingleChoiceSetting extends SettingsItem
     return mValuesId;
   }
 
-  public int getSelectedValue()
+  public int getSelectedValue(Settings settings)
   {
-    if (getSetting() == null || !(getSetting() instanceof IntSetting))
-    {
-      return mDefaultValue;
-    }
-    else
-    {
-      IntSetting setting = (IntSetting) getSetting();
-      return setting.getValue();
-    }
+    return settings.getSection(getFile(), getSection()).getInt(getKey(), mDefaultValue);
   }
 
   public MenuTag getMenuTag()
@@ -56,27 +47,9 @@ public final class SingleChoiceSetting extends SettingsItem
     return menuTag;
   }
 
-  /**
-   * 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)
+  public void setSelectedValue(Settings settings, int selection)
   {
-    if (getSetting() == null || !(getSetting() instanceof IntSetting))
-    {
-      IntSetting setting = new IntSetting(getKey(), getSection(), selection);
-      setSetting(setting);
-      return setting;
-    }
-    else
-    {
-      IntSetting setting = (IntSetting) getSetting();
-      setting.setValue(selection);
-      return null;
-    }
+    settings.getSection(getFile(), getSection()).setInt(getKey(), selection);
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSettingDynamicDescriptions.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSettingDynamicDescriptions.java
index 0f31a89088..a3135569b7 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSettingDynamicDescriptions.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SingleChoiceSettingDynamicDescriptions.java
@@ -1,7 +1,6 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
 
 public final class SingleChoiceSettingDynamicDescriptions extends SettingsItem
@@ -14,12 +13,11 @@ public final class SingleChoiceSettingDynamicDescriptions extends SettingsItem
   private int mDescriptionValuesId;
   private MenuTag menuTag;
 
-  public SingleChoiceSettingDynamicDescriptions(String key, String section, int titleId,
-          int descriptionId,
-          int choicesId, int valuesId, int descriptionChoicesId, int descriptionValuesId,
-          int defaultValue, Setting setting, MenuTag menuTag)
+  public SingleChoiceSettingDynamicDescriptions(String file, String section, String key,
+          int titleId, int descriptionId, int choicesId, int valuesId, int descriptionChoicesId,
+          int descriptionValuesId, int defaultValue, MenuTag menuTag)
   {
-    super(key, section, setting, titleId, descriptionId);
+    super(file, section, key, titleId, descriptionId);
     mValuesId = valuesId;
     mChoicesId = choicesId;
     mDescriptionChoicesId = descriptionChoicesId;
@@ -28,13 +26,12 @@ public final class SingleChoiceSettingDynamicDescriptions extends SettingsItem
     this.menuTag = menuTag;
   }
 
-  public SingleChoiceSettingDynamicDescriptions(String key, String section, int titleId,
-          int descriptionId,
-          int choicesId, int valuesId, int descriptionChoicesId, int descriptionValuesId,
-          int defaultValue, Setting setting)
+  public SingleChoiceSettingDynamicDescriptions(String file, String section, String key,
+          int titleId, int descriptionId, int choicesId, int valuesId, int descriptionChoicesId,
+          int descriptionValuesId, int defaultValue)
   {
-    this(key, section, titleId, descriptionId, choicesId, valuesId, descriptionChoicesId,
-            descriptionValuesId, defaultValue, setting, null);
+    this(file, section, key, titleId, descriptionId, choicesId, valuesId, descriptionChoicesId,
+            descriptionValuesId, defaultValue, null);
   }
 
   public int getChoicesId()
@@ -57,17 +54,9 @@ public final class SingleChoiceSettingDynamicDescriptions extends SettingsItem
     return mDescriptionValuesId;
   }
 
-  public int getSelectedValue()
+  public int getSelectedValue(Settings settings)
   {
-    if (getSetting() == null || !(getSetting() instanceof IntSetting))
-    {
-      return mDefaultValue;
-    }
-    else
-    {
-      IntSetting setting = (IntSetting) getSetting();
-      return setting.getValue();
-    }
+    return settings.getSection(getFile(), getSection()).getInt(getKey(), mDefaultValue);
   }
 
   public MenuTag getMenuTag()
@@ -75,27 +64,9 @@ public final class SingleChoiceSettingDynamicDescriptions extends SettingsItem
     return menuTag;
   }
 
-  /**
-   * 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)
+  public void setSelectedValue(Settings settings, int selection)
   {
-    if (getSetting() == null || !(getSetting() instanceof IntSetting))
-    {
-      IntSetting setting = new IntSetting(getKey(), getSection(), selection);
-      setSetting(setting);
-      return setting;
-    }
-    else
-    {
-      IntSetting setting = (IntSetting) getSetting();
-      setting.setValue(selection);
-      return null;
-    }
+    settings.getSection(getFile(), getSection()).setInt(getKey(), selection);
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SliderSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SliderSetting.java
index 93c55724a6..686c1c52d0 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SliderSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SliderSetting.java
@@ -1,117 +1,28 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.FloatSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
-import org.dolphinemu.dolphinemu.utils.Log;
 
-public final class SliderSetting extends SettingsItem
+public abstract 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)
+  public SliderSetting(String file, String section, String key, int nameId, int descriptionId,
+          int max, String units)
   {
-    super(key, section, setting, titleId, descriptionId);
+    super(file, section, key, nameId, descriptionId);
     mMax = max;
     mUnits = units;
-    mDefaultValue = defaultValue;
   }
 
+  public abstract int getSelectedValue(Settings settings);
+
   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 (isPercentSetting())
-      {
-        return Math.round(floatSetting.getValue() * 100);
-      }
-      else
-      {
-        return Math.round(floatSetting.getValue());
-      }
-    }
-    else
-    {
-      Log.error("[SliderSetting] Error casting setting type.");
-      return -1;
-    }
-  }
-
-  public boolean isPercentSetting()
-  {
-    return getKey().equals(SettingsFile.KEY_OVERCLOCK_PERCENT)
-            || getKey().equals(SettingsFile.KEY_SPEED_LIMIT);
-  }
-
-  /**
-   * 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 || !(getSetting() instanceof IntSetting))
-    {
-      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 || !(getSetting() instanceof FloatSetting))
-    {
-      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;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java
index 0dac6311c7..8532e34ccd 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/StringSingleChoiceSetting.java
@@ -1,8 +1,7 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
 import org.dolphinemu.dolphinemu.DolphinApplication;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
 
 public class StringSingleChoiceSetting extends SettingsItem
@@ -13,37 +12,37 @@ public class StringSingleChoiceSetting extends SettingsItem
   private String[] mValuesId;
   private MenuTag mMenuTag;
 
-  public StringSingleChoiceSetting(String key, String section, int titleId, int descriptionId,
-          String[] choicesId, String[] valuesId, String defaultValue, Setting setting,
+  public StringSingleChoiceSetting(String file, String section, String key, int titleId,
+          int descriptionId, String[] choicesId, String[] valuesId, String defaultValue,
           MenuTag menuTag)
   {
-    super(key, section, setting, titleId, descriptionId);
+    super(file, section, key, titleId, descriptionId);
     mChoicesId = choicesId;
     mValuesId = valuesId;
     mDefaultValue = defaultValue;
     mMenuTag = menuTag;
   }
 
-  public StringSingleChoiceSetting(String key, String section, int titleId, int descriptionId,
-          String[] choicesId, String[] valuesId, String defaultValue, Setting setting)
+  public StringSingleChoiceSetting(String file, String section, String key, int titleId,
+          int descriptionId, String[] choicesId, String[] valuesId, String defaultValue)
   {
-    this(key, section, titleId, descriptionId, choicesId, valuesId, defaultValue, setting, null);
+    this(file, section, key, titleId, descriptionId, choicesId, valuesId, defaultValue, null);
   }
 
-  public StringSingleChoiceSetting(String key, String section, int titleId, int descriptionId,
-          int choicesId, int valuesId, String defaultValue, Setting setting, MenuTag menuTag)
+  public StringSingleChoiceSetting(String file, String section, String key, int titleId,
+          int descriptionId, int choicesId, int valuesId, String defaultValue, MenuTag menuTag)
   {
-    super(key, section, setting, titleId, descriptionId);
+    super(file, section, key, titleId, descriptionId);
     mChoicesId = DolphinApplication.getAppContext().getResources().getStringArray(choicesId);
     mValuesId = DolphinApplication.getAppContext().getResources().getStringArray(valuesId);
     mDefaultValue = defaultValue;
     mMenuTag = menuTag;
   }
 
-  public StringSingleChoiceSetting(String key, String section, int titleId, int descriptionId,
-          int choicesId, int valuesId, String defaultValue, Setting setting)
+  public StringSingleChoiceSetting(String file, String section, String key, int titleId,
+          int descriptionId, int choicesId, int valuesId, String defaultValue)
   {
-    this(key, section, titleId, descriptionId, choicesId, valuesId, defaultValue, setting, null);
+    this(file, section, key, titleId, descriptionId, choicesId, valuesId, defaultValue, null);
   }
 
   public String[] getChoicesId()
@@ -69,22 +68,14 @@ public class StringSingleChoiceSetting extends SettingsItem
     return "";
   }
 
-  public String getSelectedValue()
+  public String getSelectedValue(Settings settings)
   {
-    if (getSetting() == null || !(getSetting() instanceof StringSetting))
-    {
-      return mDefaultValue;
-    }
-    else
-    {
-      StringSetting setting = (StringSetting) getSetting();
-      return setting.getValue();
-    }
+    return settings.getSection(getFile(), getSection()).getString(getKey(), mDefaultValue);
   }
 
-  public int getSelectValueIndex()
+  public int getSelectValueIndex(Settings settings)
   {
-    String selectedValue = getSelectedValue();
+    String selectedValue = getSelectedValue(settings);
     for (int i = 0; i < mValuesId.length; i++)
     {
       if (mValuesId[i].equals(selectedValue))
@@ -101,27 +92,9 @@ public class StringSingleChoiceSetting extends SettingsItem
     return mMenuTag;
   }
 
-  /**
-   * 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 StringSetting setSelectedValue(String selection)
+  public void setSelectedValue(Settings settings, String selection)
   {
-    if (getSetting() == null || !(getSetting() instanceof StringSetting))
-    {
-      StringSetting setting = new StringSetting(getKey(), getSection(), selection);
-      setSetting(setting);
-      return setting;
-    }
-    else
-    {
-      StringSetting setting = (StringSetting) getSetting();
-      setting.setValue(selection);
-      return null;
-    }
+    settings.getSection(getFile(), getSection()).setString(getKey(), selection);
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SubmenuSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SubmenuSetting.java
index 7492d30ed7..fd6f9dd346 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SubmenuSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/SubmenuSetting.java
@@ -1,15 +1,14 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
 import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
 
 public final class SubmenuSetting extends SettingsItem
 {
   private MenuTag mMenuKey;
 
-  public SubmenuSetting(String key, Setting setting, int titleId, MenuTag menuKey)
+  public SubmenuSetting(String key, int titleId, MenuTag menuKey)
   {
-    super(key, null, setting, titleId, 0);
+    super(null, null, key, titleId, 0);
     mMenuKey = menuKey;
   }
 
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
index bbdeff6227..a640c843bf 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
@@ -15,14 +15,12 @@ import android.widget.TextView;
 import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.R;
 import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog;
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.FloatSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
+import org.dolphinemu.dolphinemu.features.settings.model.view.FloatSliderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.view.IntSliderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.RumbleBindingSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSetting;
@@ -45,6 +43,7 @@ import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
 import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
 import org.dolphinemu.dolphinemu.utils.IniFile;
 
+import java.io.File;
 import java.security.InvalidParameterException;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -152,6 +151,11 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
     return getItem(position).getType();
   }
 
+  public Settings getSettings()
+  {
+    return mView.getSettings();
+  }
+
   public void setSettings(ArrayList<SettingsItem> settings)
   {
     mSettings = settings;
@@ -160,20 +164,9 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
 
   public void onBooleanClick(CheckBoxSetting item, int position, boolean checked)
   {
-    BooleanSetting setting = item.setChecked(checked);
+    item.setChecked(getSettings(), checked);
     notifyItemChanged(position);
 
-    if (setting != null)
-    {
-      mView.putSetting(setting);
-    }
-
-    if (item.getKey().equals(SettingsFile.KEY_SKIP_EFB) ||
-            item.getKey().equals(SettingsFile.KEY_IGNORE_FORMAT))
-    {
-      mView.putSetting(new BooleanSetting(item.getKey(), item.getSection(), !checked));
-    }
-
     mView.onSettingChanged(item.getKey());
   }
 
@@ -202,7 +195,8 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
             R.style.DolphinDialogBase);
 
     builder.setTitle(item.getNameId());
-    builder.setSingleChoiceItems(item.getChoicesId(), item.getSelectValueIndex(), this);
+    builder.setSingleChoiceItems(item.getChoicesId(), item.getSelectValueIndex(getSettings()),
+            this);
 
     mDialog = builder.show();
   }
@@ -228,7 +222,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
   {
     mClickedItem = item;
     mClickedPosition = position;
-    mSeekbarProgress = item.getSelectedValue();
+    mSeekbarProgress = item.getSelectedValue(getSettings());
     AlertDialog.Builder builder = new AlertDialog.Builder(mView.getActivity(),
             R.style.DolphinDialogBase);
 
@@ -262,7 +256,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
 
   public void onInputBindingClick(final InputBindingSetting item, final int position)
   {
-    final MotionAlertDialog dialog = new MotionAlertDialog(mContext, item);
+    final MotionAlertDialog dialog = new MotionAlertDialog(mContext, item, this);
     dialog.setTitle(R.string.input_binding);
     dialog.setMessage(String.format(mContext.getString(
             item instanceof RumbleBindingSetting ?
@@ -270,14 +264,10 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
             mContext.getString(item.getNameId())));
     dialog.setButton(AlertDialog.BUTTON_NEGATIVE, mContext.getString(R.string.cancel), this);
     dialog.setButton(AlertDialog.BUTTON_NEUTRAL, mContext.getString(R.string.clear),
-            (dialogInterface, i) -> item.clearValue());
+            (dialogInterface, i) -> item.clearValue(getSettings()));
     dialog.setOnDismissListener(dialog1 ->
     {
-      StringSetting setting = new StringSetting(item.getKey(), item.getSection(), item.getValue());
       notifyItemChanged(position);
-
-      mView.putSetting(setting);
-
       mView.onSettingChanged(item.getKey());
     });
     dialog.setCanceledOnTouchOutside(false);
@@ -316,13 +306,14 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
             extensions);
   }
 
-  public void onFilePickerConfirmation(String file)
+  public void onFilePickerConfirmation(String selectedFile)
   {
     FilePicker filePicker = (FilePicker) mClickedItem;
 
-    IniFile ini = new IniFile(filePicker.getFile());
-    ini.setString(filePicker.getSection(), filePicker.getKey(), file);
-    ini.save(filePicker.getFile());
+    File file = SettingsFile.getSettingsFile(filePicker.getFile());
+    IniFile ini = new IniFile(file);
+    ini.setString(filePicker.getSection(), filePicker.getKey(), selectedFile);
+    ini.save(file);
 
     NativeLibrary.ReloadConfig();
 
@@ -331,40 +322,31 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
 
   public void resetPaths()
   {
-    StringSetting defaultISO =
-            new StringSetting(SettingsFile.KEY_DEFAULT_ISO, Settings.SECTION_INI_CORE, "");
-    StringSetting NANDRootPath =
-            new StringSetting(SettingsFile.KEY_NAND_ROOT_PATH, Settings.SECTION_INI_GENERAL,
-                    SettingsFragmentPresenter.getDefaultNANDRootPath());
-    StringSetting dumpPath =
-            new StringSetting(SettingsFile.KEY_DUMP_PATH, Settings.SECTION_INI_GENERAL,
-                    SettingsFragmentPresenter.getDefaultDumpPath());
-    StringSetting loadPath =
-            new StringSetting(SettingsFile.KEY_LOAD_PATH, Settings.SECTION_INI_GENERAL,
-                    SettingsFragmentPresenter.getDefaultLoadPath());
-    StringSetting resourcePackPath =
-            new StringSetting(SettingsFile.KEY_RESOURCE_PACK_PATH, Settings.SECTION_INI_GENERAL,
-                    SettingsFragmentPresenter.getDefaultResourcePackPath());
-    StringSetting sdPath =
-            new StringSetting(SettingsFile.KEY_WII_SD_CARD_PATH, Settings.SECTION_INI_GENERAL,
-                    SettingsFragmentPresenter.getDefaultSDPath());
+    IniFile.Section coreSection = mView.getSettings().getSection(SettingsFile.FILE_NAME_DOLPHIN,
+            Settings.SECTION_INI_CORE);
+    IniFile.Section generalSection = mView.getSettings().getSection(SettingsFile.FILE_NAME_DOLPHIN,
+            Settings.SECTION_INI_GENERAL);
 
-    mView.putSetting(defaultISO);
-    mView.putSetting(NANDRootPath);
-    mView.putSetting(dumpPath);
-    mView.putSetting(loadPath);
-    mView.putSetting(resourcePackPath);
-    mView.putSetting(sdPath);
+    coreSection.delete(SettingsFile.KEY_DEFAULT_ISO);
+    generalSection.delete(SettingsFile.KEY_NAND_ROOT_PATH);
+    generalSection.delete(SettingsFile.KEY_DUMP_PATH);
+    generalSection.delete(SettingsFile.KEY_LOAD_PATH);
+    generalSection.delete(SettingsFile.KEY_RESOURCE_PACK_PATH);
+    generalSection.delete(SettingsFile.KEY_WII_SD_CARD_PATH);
 
     mView.onSettingChanged(null);
   }
 
-  public void setAllLogTypes(String value)
+  public void setAllLogTypes(boolean value)
   {
+    IniFile.Section section = mView.getSettings().getSection(SettingsFile.FILE_NAME_LOGGER,
+            Settings.SECTION_LOGGER_LOGS);
+
     for (Map.Entry<String, String> entry : SettingsFragmentPresenter.LOG_TYPE_NAMES.entrySet())
     {
-      mView.putSetting(new StringSetting(entry.getKey(), Settings.SECTION_LOGGER_LOGS, value));
+      section.setBoolean(entry.getKey(), value);
     }
+
     mView.onSettingChanged(null);
   }
 
@@ -397,17 +379,12 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
       SingleChoiceSetting scSetting = (SingleChoiceSetting) mClickedItem;
 
       int value = getValueForSingleChoiceSelection(scSetting, which);
-      if (scSetting.getSelectedValue() != value)
+      if (scSetting.getSelectedValue(getSettings()) != value)
         mView.onSettingChanged(mClickedItem.getKey());
 
       handleMenuTag(scSetting.getMenuTag(), value);
 
-      // 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);
-      }
+      scSetting.setSelectedValue(getSettings(), value);
 
       closeDialog();
     }
@@ -417,15 +394,10 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
               (SingleChoiceSettingDynamicDescriptions) mClickedItem;
 
       int value = getValueForSingleChoiceDynamicDescriptionsSelection(scSetting, which);
-      if (scSetting.getSelectedValue() != value)
+      if (scSetting.getSelectedValue(getSettings()) != value)
         mView.onSettingChanged(mClickedItem.getKey());
 
-      // 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);
-      }
+      scSetting.setSelectedValue(getSettings(), value);
 
       closeDialog();
     }
@@ -433,52 +405,32 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
     {
       StringSingleChoiceSetting scSetting = (StringSingleChoiceSetting) mClickedItem;
       String value = scSetting.getValueAt(which);
-      if (!scSetting.getSelectedValue().equals(value))
+      if (!scSetting.getSelectedValue(getSettings()).equals(value))
         mView.onSettingChanged(mClickedItem.getKey());
 
       handleMenuTag(scSetting.getMenuTag(), which);
 
-      StringSetting setting = scSetting.setSelectedValue(value);
-      if (setting != null)
-      {
-        mView.putSetting(setting);
-      }
+      scSetting.setSelectedValue(getSettings(), value);
 
       closeDialog();
     }
-    else if (mClickedItem instanceof SliderSetting)
+    else if (mClickedItem instanceof IntSliderSetting)
     {
-      SliderSetting sliderSetting = (SliderSetting) mClickedItem;
-      if (sliderSetting.getSelectedValue() != mSeekbarProgress)
+      IntSliderSetting sliderSetting = (IntSliderSetting) mClickedItem;
+      if (sliderSetting.getSelectedValue(getSettings()) != mSeekbarProgress)
         mView.onSettingChanged(mClickedItem.getKey());
 
-      if (sliderSetting.isPercentSetting() || sliderSetting.getSetting() instanceof FloatSetting)
-      {
-        float value;
+      sliderSetting.setSelectedValue(getSettings(), mSeekbarProgress);
 
-        if (sliderSetting.isPercentSetting())
-        {
-          value = mSeekbarProgress / 100.0f;
-        }
-        else
-        {
-          value = (float) mSeekbarProgress;
-        }
+      closeDialog();
+    }
+    else if (mClickedItem instanceof FloatSliderSetting)
+    {
+      FloatSliderSetting sliderSetting = (FloatSliderSetting) mClickedItem;
+      if (sliderSetting.getSelectedValue(getSettings()) != mSeekbarProgress)
+        mView.onSettingChanged(mClickedItem.getKey());
 
-        FloatSetting setting = sliderSetting.setSelectedValue(value);
-        if (setting != null)
-        {
-          mView.putSetting(setting);
-        }
-      }
-      else
-      {
-        IntSetting setting = sliderSetting.setSelectedValue(mSeekbarProgress);
-        if (setting != null)
-        {
-          mView.putSetting(setting);
-        }
-      }
+      sliderSetting.setSelectedValue(getSettings(), mSeekbarProgress);
 
       closeDialog();
     }
@@ -535,7 +487,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
 
   private int getSelectionForSingleChoiceValue(SingleChoiceSetting item)
   {
-    int value = item.getSelectedValue();
+    int value = item.getSelectedValue(getSettings());
     int valuesId = item.getValuesId();
 
     if (valuesId > 0)
@@ -577,7 +529,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
   private int getSelectionForSingleChoiceDynamicDescriptionsValue(
           SingleChoiceSettingDynamicDescriptions item)
   {
-    int value = item.getSelectedValue();
+    int value = item.getSelectedValue(getSettings());
     int valuesId = item.getValuesId();
 
     if (valuesId > 0)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java
index 16510aa929..f2be372848 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragment.java
@@ -14,7 +14,7 @@ import android.view.View;
 import android.view.ViewGroup;
 
 import org.dolphinemu.dolphinemu.R;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 import org.dolphinemu.dolphinemu.ui.DividerItemDecoration;
 
@@ -188,9 +188,9 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
   }
 
   @Override
-  public void putSetting(Setting setting)
+  public Settings getSettings()
   {
-    mPresenter.putSetting(setting);
+    return mPresenter.getSettings();
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
index 8c6d656fba..6ac485f58c 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
@@ -5,28 +5,25 @@ import android.text.TextUtils;
 
 import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.R;
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.ConfirmRunnable;
 import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
+import org.dolphinemu.dolphinemu.features.settings.model.view.FloatSliderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.HeaderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.view.IntSliderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.RumbleBindingSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSettingDynamicDescriptions;
-import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
 import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
 import org.dolphinemu.dolphinemu.utils.EGLHelper;
+import org.dolphinemu.dolphinemu.utils.IniFile;
 import org.dolphinemu.dolphinemu.utils.Log;
 
 import java.io.File;
@@ -78,9 +75,9 @@ public final class SettingsFragmentPresenter
     setSettings(settings);
   }
 
-  public void putSetting(Setting setting)
+  public Settings getSettings()
   {
-    mSettings.getSection(setting.getSection()).putSetting(setting);
+    return mSettings;
   }
 
   public void loadDefaultSettings()
@@ -208,82 +205,48 @@ public final class SettingsFragmentPresenter
 
   private void addConfigSettings(ArrayList<SettingsItem> sl)
   {
-    sl.add(new SubmenuSetting(null, null, R.string.general_submenu, MenuTag.CONFIG_GENERAL));
-    sl.add(new SubmenuSetting(null, null, R.string.interface_submenu, MenuTag.CONFIG_INTERFACE));
-    sl.add(new SubmenuSetting(null, null, R.string.audio_submenu, MenuTag.CONFIG_AUDIO));
-    sl.add(new SubmenuSetting(null, null, R.string.paths_submenu, MenuTag.CONFIG_PATHS));
-    sl.add(new SubmenuSetting(null, null, R.string.gamecube_submenu, MenuTag.CONFIG_GAME_CUBE));
-    sl.add(new SubmenuSetting(null, null, R.string.wii_submenu, MenuTag.CONFIG_WII));
-    sl.add(new SubmenuSetting(null, null, R.string.advanced_submenu, MenuTag.CONFIG_ADVANCED));
-    sl.add(new SubmenuSetting(null, null, R.string.log_submenu, MenuTag.CONFIG_LOG));
-    sl.add(new SubmenuSetting(null, null, R.string.debug_submenu, MenuTag.DEBUG));
-    sl.add(new HeaderSetting(null, null, R.string.gametdb_thanks, 0));
+    sl.add(new SubmenuSetting(null, R.string.general_submenu, MenuTag.CONFIG_GENERAL));
+    sl.add(new SubmenuSetting(null, R.string.interface_submenu, MenuTag.CONFIG_INTERFACE));
+    sl.add(new SubmenuSetting(null, R.string.audio_submenu, MenuTag.CONFIG_AUDIO));
+    sl.add(new SubmenuSetting(null, R.string.paths_submenu, MenuTag.CONFIG_PATHS));
+    sl.add(new SubmenuSetting(null, R.string.gamecube_submenu, MenuTag.CONFIG_GAME_CUBE));
+    sl.add(new SubmenuSetting(null, R.string.wii_submenu, MenuTag.CONFIG_WII));
+    sl.add(new SubmenuSetting(null, R.string.advanced_submenu, MenuTag.CONFIG_ADVANCED));
+    sl.add(new SubmenuSetting(null, R.string.log_submenu, MenuTag.CONFIG_LOG));
+    sl.add(new SubmenuSetting(null, R.string.debug_submenu, MenuTag.DEBUG));
+    sl.add(new HeaderSetting(null, R.string.gametdb_thanks, 0));
   }
 
   private void addGeneralSettings(ArrayList<SettingsItem> sl)
   {
-    Setting dualCore = null;
-    Setting overrideRegionSettings = null;
-    Setting autoDiscChange = null;
-    Setting speedLimit = null;
-    Setting analytics = null;
-    Setting enableSaveState = null;
-
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    SettingSection analyticsSection = mSettings.getSection(Settings.SECTION_ANALYTICS);
-    dualCore = coreSection.getSetting(SettingsFile.KEY_DUAL_CORE);
-    overrideRegionSettings = coreSection.getSetting(SettingsFile.KEY_OVERRIDE_REGION_SETTINGS);
-    autoDiscChange = coreSection.getSetting(SettingsFile.KEY_AUTO_DISC_CHANGE);
-    speedLimit = coreSection.getSetting(SettingsFile.KEY_SPEED_LIMIT);
-    analytics = analyticsSection.getSetting(SettingsFile.KEY_ANALYTICS_ENABLED);
-    enableSaveState = coreSection.getSetting(SettingsFile.KEY_ENABLE_SAVE_STATES);
-
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DUAL_CORE, Settings.SECTION_INI_CORE,
-            R.string.dual_core, R.string.dual_core_description, true, dualCore));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_OVERRIDE_REGION_SETTINGS,
-            Settings.SECTION_INI_CORE, R.string.override_region_settings, 0, false,
-            overrideRegionSettings));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_AUTO_DISC_CHANGE, Settings.SECTION_INI_CORE,
-            R.string.auto_disc_change, 0, false, autoDiscChange));
-    sl.add(new SliderSetting(SettingsFile.KEY_SPEED_LIMIT, Settings.SECTION_INI_CORE,
-            R.string.speed_limit, 0, 200, "%", 100, speedLimit));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_ANALYTICS_ENABLED, Settings.SECTION_ANALYTICS,
-            R.string.analytics, 0, false, analytics));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_ENABLE_SAVE_STATES, Settings.SECTION_INI_CORE,
-            R.string.enable_save_states, R.string.enable_save_states_description, false,
-            enableSaveState));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_DUAL_CORE, R.string.dual_core, R.string.dual_core_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_OVERRIDE_REGION_SETTINGS, R.string.override_region_settings, 0,
+            false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_AUTO_DISC_CHANGE, R.string.auto_disc_change, 0, false));
+    sl.add(new FloatSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_SPEED_LIMIT, R.string.speed_limit, 0, 200, "%", 100));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_ANALYTICS,
+            SettingsFile.KEY_ANALYTICS_ENABLED, R.string.analytics, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_ENABLE_SAVE_STATES, R.string.enable_save_states,
+            R.string.enable_save_states_description, false));
   }
 
   private void addInterfaceSettings(ArrayList<SettingsItem> sl)
   {
-    Setting usePanicHandlers = null;
-    Setting onScreenDisplayMessages = null;
-
-    usePanicHandlers = mSettings.getSection(Settings.SECTION_INI_INTERFACE)
-            .getSetting(SettingsFile.KEY_USE_PANIC_HANDLERS);
-    onScreenDisplayMessages = mSettings.getSection(Settings.SECTION_INI_INTERFACE)
-            .getSetting(SettingsFile.KEY_OSD_MESSAGES);
-
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_USE_PANIC_HANDLERS, Settings.SECTION_INI_INTERFACE,
-            R.string.panic_handlers, R.string.panic_handlers_description, true, usePanicHandlers));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_OSD_MESSAGES, Settings.SECTION_INI_INTERFACE,
-            R.string.osd_messages, R.string.osd_messages_description, true,
-            onScreenDisplayMessages));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_INTERFACE,
+            SettingsFile.KEY_USE_PANIC_HANDLERS, R.string.panic_handlers,
+            R.string.panic_handlers_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_INTERFACE,
+            SettingsFile.KEY_OSD_MESSAGES, R.string.osd_messages,
+            R.string.osd_messages_description, true));
   }
 
   private void addAudioSettings(ArrayList<SettingsItem> sl)
   {
-    Setting dspEmulationEngine = null;
-    Setting audioStretch = null;
-    Setting audioVolume = null;
-
-    SettingSection androidSection = mSettings.getSection(Settings.SECTION_INI_ANDROID);
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    SettingSection dspSection = mSettings.getSection(Settings.SECTION_INI_DSP);
-    dspEmulationEngine = androidSection.getSetting(SettingsFile.KEY_DSP_ENGINE);
-    audioStretch = coreSection.getSetting(SettingsFile.KEY_AUDIO_STRETCH);
-    audioVolume = dspSection.getSetting(SettingsFile.KEY_AUDIO_VOLUME);
-
     // TODO: Exclude values from arrays instead of having multiple arrays.
     int defaultCpuCore = NativeLibrary.DefaultCPUCore();
     int dspEngineEntries;
@@ -300,119 +263,74 @@ public final class SettingsFragmentPresenter
     }
     // DSP Emulation Engine controls two settings.
     // DSP Emulation Engine is read by Settings.saveSettings to modify the relevant settings.
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_DSP_ENGINE, Settings.SECTION_INI_ANDROID,
-            R.string.dsp_emulation_engine, 0, dspEngineEntries, dspEngineValues, 0,
-            dspEmulationEngine));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_AUDIO_STRETCH, Settings.SECTION_INI_CORE,
-            R.string.audio_stretch, R.string.audio_stretch_description, false, audioStretch));
-    sl.add(new SliderSetting(SettingsFile.KEY_AUDIO_VOLUME, Settings.SECTION_INI_DSP,
-            R.string.audio_volume, 0, 100, "%", 100, audioVolume));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_ANDROID,
+            SettingsFile.KEY_DSP_ENGINE, R.string.dsp_emulation_engine, 0, dspEngineEntries,
+            dspEngineValues, 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_AUDIO_STRETCH, R.string.audio_stretch,
+            R.string.audio_stretch_description, false));
+    sl.add(new IntSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_DSP,
+            SettingsFile.KEY_AUDIO_VOLUME, R.string.audio_volume, 0, 100, "%", 100));
   }
 
   private void addPathsSettings(ArrayList<SettingsItem> sl)
   {
-    Setting recursiveISOPaths = null;
-    Setting defaultISO = null;
-    Setting NANDRootPath = null;
-    Setting dumpPath = null;
-    Setting loadPath = null;
-    Setting resourcePackPath = null;
-    Setting wiiSDCardPath = null;
-
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    SettingSection generalSection = mSettings.getSection(Settings.SECTION_INI_GENERAL);
-    recursiveISOPaths = generalSection.getSetting(SettingsFile.KEY_RECURSIVE_ISO_PATHS);
-    defaultISO = coreSection.getSetting(SettingsFile.KEY_DEFAULT_ISO);
-    NANDRootPath = generalSection.getSetting(SettingsFile.KEY_NAND_ROOT_PATH);
-    dumpPath = generalSection.getSetting(SettingsFile.KEY_DUMP_PATH);
-    loadPath = generalSection.getSetting(SettingsFile.KEY_LOAD_PATH);
-    resourcePackPath = generalSection.getSetting(SettingsFile.KEY_RESOURCE_PACK_PATH);
-    wiiSDCardPath = generalSection.getSetting(SettingsFile.KEY_WII_SD_CARD_PATH);
-
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_RECURSIVE_ISO_PATHS, Settings.SECTION_INI_GENERAL,
-            R.string.search_subfolders, 0, false, recursiveISOPaths));
-    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_DEFAULT_ISO,
-            Settings.SECTION_INI_CORE, R.string.default_ISO, 0, "",
-            MainPresenter.REQUEST_GAME_FILE, defaultISO));
-    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_NAND_ROOT_PATH,
-            Settings.SECTION_INI_GENERAL, R.string.wii_NAND_root, 0, getDefaultNANDRootPath(),
-            MainPresenter.REQUEST_DIRECTORY, NANDRootPath));
-    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_DUMP_PATH,
-            Settings.SECTION_INI_GENERAL, R.string.dump_path, 0, getDefaultDumpPath(),
-            MainPresenter.REQUEST_DIRECTORY, dumpPath));
-    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_LOAD_PATH,
-            Settings.SECTION_INI_GENERAL, R.string.load_path, 0, getDefaultLoadPath(),
-            MainPresenter.REQUEST_DIRECTORY, loadPath));
-    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_RESOURCE_PACK_PATH,
-            Settings.SECTION_INI_GENERAL, R.string.resource_pack_path, 0,
-            getDefaultResourcePackPath(),
-            MainPresenter.REQUEST_DIRECTORY, resourcePackPath));
-    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_WII_SD_CARD_PATH,
-            Settings.SECTION_INI_GENERAL, R.string.SD_card_path, 0, getDefaultSDPath(),
-            MainPresenter.REQUEST_SD_FILE, wiiSDCardPath));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_RECURSIVE_ISO_PATHS, R.string.search_subfolders, 0, false));
+    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_DEFAULT_ISO, R.string.default_ISO, 0, "",
+            MainPresenter.REQUEST_GAME_FILE));
+    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_NAND_ROOT_PATH, R.string.wii_NAND_root, 0, getDefaultNANDRootPath(),
+            MainPresenter.REQUEST_DIRECTORY));
+    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_DUMP_PATH, R.string.dump_path, 0, getDefaultDumpPath(),
+            MainPresenter.REQUEST_DIRECTORY));
+    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_LOAD_PATH, R.string.load_path, 0, getDefaultLoadPath(),
+            MainPresenter.REQUEST_DIRECTORY));
+    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_RESOURCE_PACK_PATH, R.string.resource_pack_path, 0,
+            getDefaultResourcePackPath(), MainPresenter.REQUEST_DIRECTORY));
+    sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_GENERAL,
+            SettingsFile.KEY_WII_SD_CARD_PATH, R.string.SD_card_path, 0, getDefaultSDPath(),
+            MainPresenter.REQUEST_SD_FILE));
     sl.add(new ConfirmRunnable(R.string.reset_paths, 0, R.string.reset_paths_confirmation, 0,
             mView.getAdapter()::resetPaths));
   }
 
   private void addGameCubeSettings(ArrayList<SettingsItem> sl)
   {
-    Setting systemLanguage = null;
-    Setting slotADevice = null;
-    Setting slotBDevice = null;
-
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    systemLanguage = coreSection.getSetting(SettingsFile.KEY_GAME_CUBE_LANGUAGE);
-    slotADevice = coreSection.getSetting(SettingsFile.KEY_SLOT_A_DEVICE);
-    slotBDevice = coreSection.getSetting(SettingsFile.KEY_SLOT_B_DEVICE);
-
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_GAME_CUBE_LANGUAGE, Settings.SECTION_INI_CORE,
-            R.string.gamecube_system_language, 0, R.array.gameCubeSystemLanguageEntries,
-            R.array.gameCubeSystemLanguageValues, 0, systemLanguage));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_SLOT_A_DEVICE, Settings.SECTION_INI_CORE,
-            R.string.slot_a_device, 0, R.array.slotDeviceEntries, R.array.slotDeviceValues, 8,
-            slotADevice));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_SLOT_B_DEVICE, Settings.SECTION_INI_CORE,
-            R.string.slot_b_device, 0, R.array.slotDeviceEntries, R.array.slotDeviceValues, 255,
-            slotBDevice));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_GAME_CUBE_LANGUAGE, R.string.gamecube_system_language, 0,
+            R.array.gameCubeSystemLanguageEntries, R.array.gameCubeSystemLanguageValues, 0));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_SLOT_A_DEVICE, R.string.slot_a_device, 0, R.array.slotDeviceEntries,
+            R.array.slotDeviceValues, 8));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_SLOT_B_DEVICE, R.string.slot_b_device, 0, R.array.slotDeviceEntries,
+            R.array.slotDeviceValues, 255));
   }
 
   private void addWiiSettings(ArrayList<SettingsItem> sl)
   {
-    Setting wiiSDCard = null;
-    Setting wiiSDWrites = null;
-    Setting continuousScan = null;
-    Setting wiimoteSpeaker = null;
-
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    wiiSDCard = coreSection.getSetting(SettingsFile.KEY_WII_SD_CARD);
-    wiiSDWrites = coreSection.getSetting(SettingsFile.KEY_WII_SD_CARD_ALLOW_WRITES);
-    continuousScan = coreSection.getSetting(SettingsFile.KEY_WIIMOTE_SCAN);
-    wiimoteSpeaker = coreSection.getSetting(SettingsFile.KEY_WIIMOTE_SPEAKER);
-
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_WII_SD_CARD, Settings.SECTION_INI_CORE,
-            R.string.insert_sd_card, R.string.insert_sd_card_description, true, wiiSDCard));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_WII_SD_CARD_ALLOW_WRITES, Settings.SECTION_INI_CORE,
-            R.string.wii_sd_card_allow_writes, 0, true, wiiSDWrites));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_WIIMOTE_SCAN, Settings.SECTION_INI_CORE,
-            R.string.wiimote_scanning, R.string.wiimote_scanning_description, false,
-            continuousScan));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_WIIMOTE_SPEAKER, Settings.SECTION_INI_CORE,
-            R.string.wiimote_speaker, R.string.wiimote_speaker_description, false, wiimoteSpeaker));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_WII_SD_CARD, R.string.insert_sd_card,
+            R.string.insert_sd_card_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_WII_SD_CARD_ALLOW_WRITES, R.string.wii_sd_card_allow_writes, 0, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_WIIMOTE_SCAN, R.string.wiimote_scanning,
+            R.string.wiimote_scanning_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_WIIMOTE_SPEAKER, R.string.wiimote_speaker,
+            R.string.wiimote_speaker_description, false));
   }
 
   private void addAdvancedSettings(ArrayList<SettingsItem> sl)
   {
-    Setting cpuCore = null;
-    Setting overclockEnable = null;
-    Setting overclock = null;
-
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    cpuCore = coreSection.getSetting(SettingsFile.KEY_CPU_CORE);
-    overclockEnable = coreSection.getSetting(SettingsFile.KEY_OVERCLOCK_ENABLE);
-    overclock = coreSection.getSetting(SettingsFile.KEY_OVERCLOCK_PERCENT);
-
     // TODO: Having different emuCoresEntries/emuCoresValues for each architecture is annoying.
-    //       The proper solution would be to have one emuCoresEntries and one emuCoresValues
+    //       The proper solution would be to have one set of entries and one set of values
     //       and exclude the values that aren't present in PowerPC::AvailableCPUCores().
     int defaultCpuCore = NativeLibrary.DefaultCPUCore();
     int emuCoresEntries;
@@ -432,14 +350,15 @@ public final class SettingsFragmentPresenter
       emuCoresEntries = R.array.emuCoresEntriesGeneric;
       emuCoresValues = R.array.emuCoresValuesGeneric;
     }
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_CPU_CORE, Settings.SECTION_INI_CORE,
-            R.string.cpu_core, 0, emuCoresEntries, emuCoresValues, defaultCpuCore, cpuCore));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_OVERCLOCK_ENABLE, Settings.SECTION_INI_CORE,
-            R.string.overclock_enable, R.string.overclock_enable_description, false,
-            overclockEnable));
-    sl.add(new SliderSetting(SettingsFile.KEY_OVERCLOCK_PERCENT, Settings.SECTION_INI_CORE,
-            R.string.overclock_title, R.string.overclock_title_description, 400, "%", 100,
-            overclock));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_CPU_CORE, R.string.cpu_core, 0, emuCoresEntries, emuCoresValues,
+            defaultCpuCore));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_OVERCLOCK_ENABLE, R.string.overclock_enable,
+            R.string.overclock_enable_description, false));
+    sl.add(new FloatSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_OVERCLOCK_PERCENT, R.string.overclock_title,
+            R.string.overclock_title_description, 400, "%", 100));
   }
 
   private void addGcPadSettings(ArrayList<SettingsItem> sl)
@@ -449,19 +368,16 @@ public final class SettingsFragmentPresenter
       if (mGameID.equals(""))
       {
         // TODO: This controller_0 + i business is quite the hack. It should work, but only if the definitions are kept together and in order.
-        Setting gcPadSetting = mSettings.getSection(Settings.SECTION_INI_CORE)
-                .getSetting(SettingsFile.KEY_GCPAD_TYPE + i);
-        sl.add(new SingleChoiceSetting(SettingsFile.KEY_GCPAD_TYPE + i, Settings.SECTION_INI_CORE,
-                R.string.controller_0 + i, 0, R.array.gcpadTypeEntries, R.array.gcpadTypeValues, 0,
-                gcPadSetting, MenuTag.getGCPadMenuTag(i)));
+        sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+                SettingsFile.KEY_GCPAD_TYPE + i, R.string.controller_0 + i, 0,
+                R.array.gcpadTypeEntries, R.array.gcpadTypeValues, 0, MenuTag.getGCPadMenuTag(i)));
       }
       else
       {
-        Setting gcPadSetting = mSettings.getSection(Settings.SECTION_CONTROLS)
-                .getSetting(SettingsFile.KEY_GCPAD_G_TYPE + i);
-        sl.add(new SingleChoiceSetting(SettingsFile.KEY_GCPAD_G_TYPE + i, Settings.SECTION_CONTROLS,
+        sl.add(new SingleChoiceSetting(Settings.GAME_SETTINGS_PLACEHOLDER_FILE_NAME,
+                Settings.SECTION_CONTROLS, SettingsFile.KEY_GCPAD_G_TYPE + i,
                 R.string.controller_0 + i, 0, R.array.gcpadTypeEntries, R.array.gcpadTypeValues, 0,
-                gcPadSetting, MenuTag.getGCPadMenuTag(i)));
+                MenuTag.getGCPadMenuTag(i)));
       }
     }
   }
@@ -473,137 +389,101 @@ public final class SettingsFragmentPresenter
       // TODO: This wiimote_0 + i business is quite the hack. It should work, but only if the definitions are kept together and in order.
       if (mGameID.equals(""))
       {
-        Setting wiimoteSetting = mSettings.getSection(Settings.SECTION_WIIMOTE + (i + 1))
-                .getSetting(SettingsFile.KEY_WIIMOTE_TYPE);
-        sl.add(new SingleChoiceSetting(SettingsFile.KEY_WIIMOTE_TYPE,
-                Settings.SECTION_WIIMOTE + (i + 1), R.string.wiimote_4 + i, 0,
-                R.array.wiimoteTypeEntries, R.array.wiimoteTypeValues, 0, wiimoteSetting,
-                MenuTag.getWiimoteMenuTag(i + 4)));
+        sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_WIIMOTE,
+                Settings.SECTION_WIIMOTE + (i + 1), SettingsFile.KEY_WIIMOTE_TYPE,
+                R.string.wiimote_4 + i, 0, R.array.wiimoteTypeEntries, R.array.wiimoteTypeValues,
+                0, MenuTag.getWiimoteMenuTag(i + 4)));
       }
       else
       {
-        Setting wiimoteSetting = mSettings.getSection(Settings.SECTION_CONTROLS)
-                .getSetting(SettingsFile.KEY_WIIMOTE_G_TYPE + i);
-        sl.add(new SingleChoiceSetting(SettingsFile.KEY_WIIMOTE_G_TYPE + i,
-                Settings.SECTION_CONTROLS, R.string.wiimote_4 + i, 0, R.array.wiimoteTypeEntries,
-                R.array.wiimoteTypeValues, 0, wiimoteSetting, MenuTag.getWiimoteMenuTag(i + 4)));
+        sl.add(new SingleChoiceSetting(Settings.GAME_SETTINGS_PLACEHOLDER_FILE_NAME,
+                Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIMOTE_G_TYPE + i,
+                R.string.wiimote_4 + i, 0, R.array.wiimoteTypeEntries, R.array.wiimoteTypeValues,
+                0, MenuTag.getWiimoteMenuTag(i + 4)));
       }
     }
   }
 
   private void addGraphicsSettings(ArrayList<SettingsItem> sl)
   {
-    Setting videoBackend = null;
-    Setting showFps = null;
-    Setting shaderCompilationMode = null;
-    Setting waitForShaders = null;
-    Setting aspectRatio = null;
-
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-    videoBackend = coreSection.getSetting(SettingsFile.KEY_VIDEO_BACKEND);
-
-    SettingSection gfxSection = mSettings.getSection(Settings.SECTION_GFX_SETTINGS);
-    showFps = gfxSection.getSetting(SettingsFile.KEY_SHOW_FPS);
-    shaderCompilationMode = gfxSection.getSetting(SettingsFile.KEY_SHADER_COMPILATION_MODE);
-    waitForShaders = gfxSection.getSetting(SettingsFile.KEY_WAIT_FOR_SHADERS);
-    aspectRatio = gfxSection.getSetting(SettingsFile.KEY_ASPECT_RATIO);
-
-    sl.add(new HeaderSetting(null, null, R.string.graphics_general, 0));
-    sl.add(new StringSingleChoiceSetting(SettingsFile.KEY_VIDEO_BACKEND, Settings.SECTION_INI_CORE,
-            R.string.video_backend, 0, R.array.videoBackendEntries,
-            R.array.videoBackendValues, "OGL", videoBackend));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_SHOW_FPS, Settings.SECTION_GFX_SETTINGS,
-            R.string.show_fps, R.string.show_fps_description, false, showFps));
-    sl.add(new SingleChoiceSettingDynamicDescriptions(SettingsFile.KEY_SHADER_COMPILATION_MODE,
-            Settings.SECTION_GFX_SETTINGS, R.string.shader_compilation_mode, 0,
-            R.array.shaderCompilationModeEntries,
+    sl.add(new HeaderSetting(null, R.string.graphics_general, 0));
+    sl.add(new StringSingleChoiceSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+            SettingsFile.KEY_VIDEO_BACKEND, R.string.video_backend, 0,
+            R.array.videoBackendEntries, R.array.videoBackendValues, "OGL"));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_SHOW_FPS, R.string.show_fps, R.string.show_fps_description, false));
+    sl.add(new SingleChoiceSettingDynamicDescriptions(SettingsFile.FILE_NAME_GFX,
+            Settings.SECTION_GFX_SETTINGS, SettingsFile.KEY_SHADER_COMPILATION_MODE,
+            R.string.shader_compilation_mode, 0, R.array.shaderCompilationModeEntries,
             R.array.shaderCompilationModeValues, R.array.shaderCompilationDescriptionEntries,
-            R.array.shaderCompilationDescriptionValues, 0, shaderCompilationMode));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_WAIT_FOR_SHADERS, Settings.SECTION_GFX_SETTINGS,
-            R.string.wait_for_shaders, R.string.wait_for_shaders_description, false,
-            waitForShaders));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_ASPECT_RATIO, Settings.SECTION_GFX_SETTINGS,
-            R.string.aspect_ratio, 0, R.array.aspectRatioEntries,
-            R.array.aspectRatioValues, 0, aspectRatio));
+            R.array.shaderCompilationDescriptionValues, 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_WAIT_FOR_SHADERS, R.string.wait_for_shaders,
+            R.string.wait_for_shaders_description, false));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_ASPECT_RATIO, R.string.aspect_ratio, 0, R.array.aspectRatioEntries,
+            R.array.aspectRatioValues, 0));
 
-    sl.add(new HeaderSetting(null, null, R.string.graphics_enhancements_and_hacks, 0));
-    sl.add(new SubmenuSetting(null, null, R.string.enhancements_submenu, MenuTag.ENHANCEMENTS));
-    sl.add(new SubmenuSetting(null, null, R.string.hacks_submenu, MenuTag.HACKS));
+    sl.add(new HeaderSetting(null, R.string.graphics_enhancements_and_hacks, 0));
+    sl.add(new SubmenuSetting(null, R.string.enhancements_submenu, MenuTag.ENHANCEMENTS));
+    sl.add(new SubmenuSetting(null, R.string.hacks_submenu, MenuTag.HACKS));
   }
 
   private void addEnhanceSettings(ArrayList<SettingsItem> sl)
   {
-    SettingSection gfxSection = mSettings.getSection(Settings.SECTION_GFX_SETTINGS);
-    SettingSection enhancementSection = mSettings.getSection(Settings.SECTION_GFX_ENHANCEMENTS);
-    SettingSection hacksSection = mSettings.getSection(Settings.SECTION_GFX_HACKS);
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_INTERNAL_RES, R.string.internal_resolution,
+            R.string.internal_resolution_description, R.array.internalResolutionEntries,
+            R.array.internalResolutionValues, 1));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_FSAA, R.string.FSAA, R.string.FSAA_description, R.array.FSAAEntries,
+            R.array.FSAAValues, 1));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
+            SettingsFile.KEY_ANISOTROPY, R.string.anisotropic_filtering,
+            R.string.anisotropic_filtering_description, R.array.anisotropicFilteringEntries,
+            R.array.anisotropicFilteringValues, 0));
 
-    Setting resolution = gfxSection.getSetting(SettingsFile.KEY_INTERNAL_RES);
-    Setting fsaa = gfxSection.getSetting(SettingsFile.KEY_FSAA);
-    Setting anisotropic = enhancementSection.getSetting(SettingsFile.KEY_ANISOTROPY);
-    Setting shader = enhancementSection.getSetting(SettingsFile.KEY_POST_SHADER);
-    Setting efbScaledCopy = hacksSection.getSetting(SettingsFile.KEY_SCALED_EFB);
-    Setting perPixel = gfxSection.getSetting(SettingsFile.KEY_PER_PIXEL);
-    Setting forceFilter = enhancementSection.getSetting(SettingsFile.KEY_FORCE_FILTERING);
-    Setting disableFog = gfxSection.getSetting(SettingsFile.KEY_DISABLE_FOG);
-    Setting disableCopyFilter = enhancementSection.getSetting(SettingsFile.KEY_DISABLE_COPY_FILTER);
-    Setting arbitraryMipmapDetection =
-            enhancementSection.getSetting(SettingsFile.KEY_ARBITRARY_MIPMAP_DETECTION);
-    Setting wideScreenHack = gfxSection.getSetting(SettingsFile.KEY_WIDE_SCREEN_HACK);
-    Setting force24BitColor = enhancementSection.getSetting(SettingsFile.KEY_FORCE_24_BIT_COLOR);
-    Setting backendMultithreading = gfxSection.getSetting(SettingsFile.KEY_BACKEND_MULTITHREADING);
-
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_INTERNAL_RES, Settings.SECTION_GFX_SETTINGS,
-            R.string.internal_resolution, R.string.internal_resolution_description,
-            R.array.internalResolutionEntries, R.array.internalResolutionValues, 1, resolution));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_FSAA, Settings.SECTION_GFX_SETTINGS,
-            R.string.FSAA, R.string.FSAA_description, R.array.FSAAEntries, R.array.FSAAValues, 1,
-            fsaa));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_ANISOTROPY, Settings.SECTION_GFX_ENHANCEMENTS,
-            R.string.anisotropic_filtering, R.string.anisotropic_filtering_description,
-            R.array.anisotropicFilteringEntries, R.array.anisotropicFilteringValues, 0,
-            anisotropic));
-
-    IntSetting stereoModeValue = (IntSetting) gfxSection.getSetting(SettingsFile.KEY_STEREO_MODE);
-    int anaglyphMode = 3;
-    String subDir =
-            stereoModeValue != null && stereoModeValue.getValue() == anaglyphMode ? "Anaglyph" :
-                    null;
+    int stereoModeValue =
+            mSettings.getSection(SettingsFile.FILE_NAME_GFX, Settings.SECTION_STEREOSCOPY)
+                    .getInt(SettingsFile.KEY_STEREO_MODE, 0);
+    final int anaglyphMode = 3;
+    String subDir = stereoModeValue == anaglyphMode ? "Anaglyph" : null;
     String[] shaderListEntries = getShaderList(subDir);
     String[] shaderListValues = new String[shaderListEntries.length];
     System.arraycopy(shaderListEntries, 0, shaderListValues, 0, shaderListEntries.length);
     shaderListValues[0] = "";
-    sl.add(new StringSingleChoiceSetting(SettingsFile.KEY_POST_SHADER,
-            Settings.SECTION_GFX_ENHANCEMENTS, R.string.post_processing_shader,
-            0, shaderListEntries, shaderListValues, "",
-            shader));
+    sl.add(new StringSingleChoiceSetting(SettingsFile.FILE_NAME_GFX,
+            Settings.SECTION_GFX_ENHANCEMENTS, SettingsFile.KEY_POST_SHADER,
+            R.string.post_processing_shader, 0, shaderListEntries, shaderListValues, ""));
 
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_SCALED_EFB, Settings.SECTION_GFX_HACKS,
-            R.string.scaled_efb_copy, R.string.scaled_efb_copy_description, true, efbScaledCopy));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_PER_PIXEL, Settings.SECTION_GFX_SETTINGS,
-            R.string.per_pixel_lighting, R.string.per_pixel_lighting_description, false, perPixel));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_FORCE_FILTERING, Settings.SECTION_GFX_ENHANCEMENTS,
-            R.string.force_texture_filtering, R.string.force_texture_filtering_description, false,
-            forceFilter));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_FORCE_24_BIT_COLOR,
-            Settings.SECTION_GFX_ENHANCEMENTS,
-            R.string.force_24bit_color, R.string.force_24bit_color_description, true,
-            force24BitColor));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DISABLE_FOG, Settings.SECTION_GFX_SETTINGS,
-            R.string.disable_fog, R.string.disable_fog_description, false, disableFog));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DISABLE_COPY_FILTER,
-            Settings.SECTION_GFX_ENHANCEMENTS,
-            R.string.disable_copy_filter, R.string.disable_copy_filter_description, false,
-            disableCopyFilter));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_ARBITRARY_MIPMAP_DETECTION,
-            Settings.SECTION_GFX_ENHANCEMENTS, R.string.arbitrary_mipmap_detection,
-            R.string.arbitrary_mipmap_detection_description, true, arbitraryMipmapDetection));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_WIDE_SCREEN_HACK, Settings.SECTION_GFX_SETTINGS,
-            R.string.wide_screen_hack, R.string.wide_screen_hack_description, false,
-            wideScreenHack));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_BACKEND_MULTITHREADING,
-            Settings.SECTION_GFX_SETTINGS,
-            R.string.backend_multithreading, R.string.backend_multithreading_description, false,
-            backendMultithreading));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_SCALED_EFB, R.string.scaled_efb_copy,
+            R.string.scaled_efb_copy_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_PER_PIXEL, R.string.per_pixel_lighting,
+            R.string.per_pixel_lighting_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
+            SettingsFile.KEY_FORCE_FILTERING, R.string.force_texture_filtering,
+            R.string.force_texture_filtering_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX,
+            Settings.SECTION_GFX_ENHANCEMENTS, SettingsFile.KEY_FORCE_24_BIT_COLOR,
+            R.string.force_24bit_color, R.string.force_24bit_color_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_DISABLE_FOG, R.string.disable_fog, R.string.disable_fog_description,
+            false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
+            SettingsFile.KEY_DISABLE_COPY_FILTER, R.string.disable_copy_filter,
+            R.string.disable_copy_filter_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_ENHANCEMENTS,
+            SettingsFile.KEY_ARBITRARY_MIPMAP_DETECTION, R.string.arbitrary_mipmap_detection,
+            R.string.arbitrary_mipmap_detection_description,
+            true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_WIDE_SCREEN_HACK, R.string.wide_screen_hack,
+            R.string.wide_screen_hack_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_BACKEND_MULTITHREADING, R.string.backend_multithreading,
+            R.string.backend_multithreading_description, false));
 
      /*
      Check if we support stereo
@@ -616,7 +496,7 @@ public final class SettingsFragmentPresenter
             (helper.supportsGLES3() && helper.GetVersion() >= 310 &&
                     helper.SupportsExtension("GL_ANDROID_extension_pack_es31a")))
     {
-      sl.add(new SubmenuSetting(SettingsFile.KEY_STEREO_MODE, null, R.string.stereoscopy_submenu,
+      sl.add(new SubmenuSetting(SettingsFile.KEY_STEREO_MODE, R.string.stereoscopy_submenu,
               MenuTag.STEREOSCOPY));
     }
   }
@@ -663,937 +543,638 @@ public final class SettingsFragmentPresenter
 
   private void addHackSettings(ArrayList<SettingsItem> sl)
   {
-    SettingSection gfxSection = mSettings.getSection(Settings.SECTION_GFX_SETTINGS);
-    SettingSection hacksSection = mSettings.getSection(Settings.SECTION_GFX_HACKS);
+    sl.add(new HeaderSetting(null, R.string.embedded_frame_buffer, 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_SKIP_EFB, R.string.skip_efb_access,
+            R.string.skip_efb_access_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_IGNORE_FORMAT, R.string.ignore_format_changes,
+            R.string.ignore_format_changes_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_EFB_TEXTURE, R.string.efb_copy_method,
+            R.string.efb_copy_method_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_DEFER_EFB_COPIES, R.string.defer_efb_copies,
+            R.string.defer_efb_copies_description, true));
 
-    boolean skipEFBValue =
-            getInvertedBooleanValue(Settings.SECTION_GFX_HACKS, SettingsFile.KEY_SKIP_EFB, false);
-    boolean ignoreFormatValue =
-            getInvertedBooleanValue(Settings.SECTION_GFX_HACKS, SettingsFile.KEY_IGNORE_FORMAT,
-                    true);
-
-    BooleanSetting skipEFB =
-            new BooleanSetting(SettingsFile.KEY_SKIP_EFB, Settings.SECTION_GFX_HACKS, skipEFBValue);
-    BooleanSetting ignoreFormat =
-            new BooleanSetting(SettingsFile.KEY_IGNORE_FORMAT, Settings.SECTION_GFX_HACKS,
-                    ignoreFormatValue);
-    Setting efbToTexture = hacksSection.getSetting(SettingsFile.KEY_EFB_TEXTURE);
-    Setting deferEfbCopies = hacksSection.getSetting(SettingsFile.KEY_DEFER_EFB_COPIES);
-    Setting texCacheAccuracy = gfxSection.getSetting(SettingsFile.KEY_TEXCACHE_ACCURACY);
-    Setting gpuTextureDecoding = gfxSection.getSetting(SettingsFile.KEY_GPU_TEXTURE_DECODING);
-    Setting xfbToTexture = hacksSection.getSetting(SettingsFile.KEY_XFB_TEXTURE);
-    Setting immediateXfb = hacksSection.getSetting(SettingsFile.KEY_IMMEDIATE_XFB);
-    Setting skipDuplicateXfbs = hacksSection.getSetting(SettingsFile.KEY_SKIP_DUPLICATE_XFBS);
-    Setting fastDepth = gfxSection.getSetting(SettingsFile.KEY_FAST_DEPTH);
-
-    sl.add(new HeaderSetting(null, null, R.string.embedded_frame_buffer, 0));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_SKIP_EFB, Settings.SECTION_GFX_HACKS,
-            R.string.skip_efb_access, R.string.skip_efb_access_description, false, skipEFB));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_IGNORE_FORMAT, Settings.SECTION_GFX_HACKS,
-            R.string.ignore_format_changes, R.string.ignore_format_changes_description, true,
-            ignoreFormat));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_EFB_TEXTURE, Settings.SECTION_GFX_HACKS,
-            R.string.efb_copy_method, R.string.efb_copy_method_description, true, efbToTexture));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEFER_EFB_COPIES, Settings.SECTION_GFX_HACKS,
-            R.string.defer_efb_copies, R.string.defer_efb_copies_description, true,
-            deferEfbCopies));
-
-    sl.add(new HeaderSetting(null, null, R.string.texture_cache, 0));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_TEXCACHE_ACCURACY,
-            Settings.SECTION_GFX_SETTINGS, R.string.texture_cache_accuracy,
+    sl.add(new HeaderSetting(null, R.string.texture_cache, 0));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_TEXCACHE_ACCURACY, R.string.texture_cache_accuracy,
             R.string.texture_cache_accuracy_description, R.array.textureCacheAccuracyEntries,
-            R.array.textureCacheAccuracyValues, 128, texCacheAccuracy));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_GPU_TEXTURE_DECODING, Settings.SECTION_GFX_SETTINGS,
-            R.string.gpu_texture_decoding, R.string.gpu_texture_decoding_description, false,
-            gpuTextureDecoding));
+            R.array.textureCacheAccuracyValues, 128));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_GPU_TEXTURE_DECODING, R.string.gpu_texture_decoding,
+            R.string.gpu_texture_decoding_description, false));
 
-    sl.add(new HeaderSetting(null, null, R.string.external_frame_buffer, 0));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_XFB_TEXTURE, Settings.SECTION_GFX_HACKS,
-            R.string.xfb_copy_method, R.string.xfb_copy_method_description, true, xfbToTexture));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_IMMEDIATE_XFB, Settings.SECTION_GFX_HACKS,
-            R.string.immediate_xfb, R.string.immediate_xfb_description, false, immediateXfb));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_SKIP_DUPLICATE_XFBS, Settings.SECTION_GFX_HACKS,
-            R.string.skip_duplicate_xfbs, R.string.skip_duplicate_xfbs_description, true,
-            skipDuplicateXfbs));
+    sl.add(new HeaderSetting(null, R.string.external_frame_buffer, 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_XFB_TEXTURE, R.string.xfb_copy_method,
+            R.string.xfb_copy_method_description, true));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_IMMEDIATE_XFB, R.string.immediate_xfb,
+            R.string.immediate_xfb_description, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+            SettingsFile.KEY_SKIP_DUPLICATE_XFBS, R.string.skip_duplicate_xfbs,
+            R.string.skip_duplicate_xfbs_description, true));
 
-    sl.add(new HeaderSetting(null, null, R.string.other, 0));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_FAST_DEPTH, Settings.SECTION_GFX_SETTINGS,
-            R.string.fast_depth_calculation, R.string.fast_depth_calculation_description, true,
-            fastDepth));
+    sl.add(new HeaderSetting(null, R.string.other, 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_SETTINGS,
+            SettingsFile.KEY_FAST_DEPTH, R.string.fast_depth_calculation,
+            R.string.fast_depth_calculation_description, true));
   }
 
   private void addLogConfigurationSettings(ArrayList<SettingsItem> sl)
   {
-    SettingSection logsSection = mSettings.getSection(Settings.SECTION_LOGGER_LOGS);
-    SettingSection optionsSection = mSettings.getSection(Settings.SECTION_LOGGER_OPTIONS);
-    Setting enableLogging = optionsSection.getSetting(SettingsFile.KEY_ENABLE_LOGGING);
-    Setting logVerbosity = optionsSection.getSetting(SettingsFile.KEY_LOG_VERBOSITY);
-
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_ENABLE_LOGGING, Settings.SECTION_LOGGER_OPTIONS,
-            R.string.enable_logging, R.string.enable_logging_description, false, enableLogging));
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_LOG_VERBOSITY, Settings.SECTION_LOGGER_OPTIONS,
-            R.string.log_verbosity, 0, getLogVerbosityEntries(), getLogVerbosityValues(), 1,
-            logVerbosity));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_LOGGER, Settings.SECTION_LOGGER_OPTIONS,
+            SettingsFile.KEY_ENABLE_LOGGING, R.string.enable_logging,
+            R.string.enable_logging_description, false));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_LOGGER, Settings.SECTION_LOGGER_OPTIONS,
+            SettingsFile.KEY_LOG_VERBOSITY, R.string.log_verbosity, 0, getLogVerbosityEntries(),
+            getLogVerbosityValues(), 1));
     sl.add(new ConfirmRunnable(R.string.log_enable_all, 0, R.string.log_enable_all_confirmation, 0,
-            () -> mView.getAdapter().setAllLogTypes("True")));
+            () -> mView.getAdapter().setAllLogTypes(true)));
     sl.add(new ConfirmRunnable(R.string.log_disable_all, 0, R.string.log_disable_all_confirmation,
-            0, () -> mView.getAdapter().setAllLogTypes("False")));
+            0, () -> mView.getAdapter().setAllLogTypes(false)));
 
-    sl.add(new HeaderSetting(null, null, R.string.log_types, 0));
+    sl.add(new HeaderSetting(null, R.string.log_types, 0));
     for (Map.Entry<String, String> entry : LOG_TYPE_NAMES.entrySet())
     {
-      Setting setting = logsSection.getSetting(entry.getKey());
       // TitleID is handled by special case in CheckBoxSettingViewHolder.
-      sl.add(
-              new CheckBoxSetting(entry.getKey(), Settings.SECTION_LOGGER_LOGS, 0, 0, false,
-                      setting));
+      sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_LOGGER, Settings.SECTION_LOGGER_LOGS,
+              entry.getKey(), 0, 0, false));
     }
   }
 
   private void addDebugSettings(ArrayList<SettingsItem> sl)
   {
-    SettingSection debugSection = mSettings.getSection(Settings.SECTION_DEBUG);
+    sl.add(new HeaderSetting(null, R.string.debug_warning, 0));
 
-    Setting jitOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITOFF);
-    Setting jitLoadStoreOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITLOADSTOREOFF);
-    Setting jitLoadStoreFloatingPointOff =
-            debugSection.getSetting(SettingsFile.KEY_DEBUG_JITLOADSTOREFLOATINGPOINTOFF);
-    Setting jitLoadStorePairedOff =
-            debugSection.getSetting(SettingsFile.KEY_DEBUG_JITLOADSTOREPAIREDOFF);
-    Setting jitFloatingPointOff =
-            debugSection.getSetting(SettingsFile.KEY_DEBUG_JITFLOATINGPOINTOFF);
-    Setting jitIntegerOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITINTEGEROFF);
-    Setting jitPairedOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITPAIREDOFF);
-    Setting jitSystemRegistersOff =
-            debugSection.getSetting(SettingsFile.KEY_DEBUG_JITSYSTEMREGISTEROFF);
-    Setting jitBranchOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITBRANCHOFF);
-    Setting jitRegisterCacheOff =
-            debugSection.getSetting(SettingsFile.KEY_DEBUG_JITREGISTERCACHEOFF);
-
-    sl.add(new HeaderSetting(null, null, R.string.debug_warning, 0));
-
-    sl.add(new HeaderSetting(null, null, R.string.debug_jit_header, 0));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitoff, 0, false,
-            jitOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITLOADSTOREOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitloadstoreoff, 0, false,
-            jitLoadStoreOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITLOADSTOREFLOATINGPOINTOFF,
-            Settings.SECTION_DEBUG,
-            R.string.debug_jitloadstorefloatingoff, 0, false,
-            jitLoadStoreFloatingPointOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITLOADSTOREPAIREDOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitloadstorepairedoff, 0, false,
-            jitLoadStorePairedOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITFLOATINGPOINTOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitfloatingpointoff, 0, false,
-            jitFloatingPointOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITINTEGEROFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitintegeroff, 0, false,
-            jitIntegerOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITPAIREDOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitpairedoff, 0, false,
-            jitPairedOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITSYSTEMREGISTEROFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitsystemregistersoffr, 0, false,
-            jitSystemRegistersOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITBRANCHOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitbranchoff, 0, false,
-            jitBranchOff));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITREGISTERCACHEOFF, Settings.SECTION_DEBUG,
-            R.string.debug_jitregistercacheoff, 0, false,
-            jitRegisterCacheOff));
+    sl.add(new HeaderSetting(null, R.string.debug_jit_header, 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITOFF, R.string.debug_jitoff, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITLOADSTOREOFF, R.string.debug_jitloadstoreoff, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN,
+            SettingsFile.KEY_DEBUG_JITLOADSTOREFLOATINGPOINTOFF, Settings.SECTION_DEBUG,
+            R.string.debug_jitloadstorefloatingoff, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITLOADSTOREPAIREDOFF, R.string.debug_jitloadstorepairedoff, 0,
+            false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITFLOATINGPOINTOFF, R.string.debug_jitfloatingpointoff, 0,
+            false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITINTEGEROFF, R.string.debug_jitintegeroff, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITPAIREDOFF, R.string.debug_jitpairedoff, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITSYSTEMREGISTEROFF, R.string.debug_jitsystemregistersoffr, 0,
+            false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITBRANCHOFF, R.string.debug_jitbranchoff, 0, false));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_DEBUG,
+            SettingsFile.KEY_DEBUG_JITREGISTERCACHEOFF, R.string.debug_jitregistercacheoff, 0,
+            false));
   }
 
   private void addStereoSettings(ArrayList<SettingsItem> sl)
   {
-    SettingSection stereoScopySection = mSettings.getSection(Settings.SECTION_STEREOSCOPY);
-
-    Setting stereoModeValue = stereoScopySection.getSetting(SettingsFile.KEY_STEREO_MODE);
-    Setting stereoDepth = stereoScopySection.getSetting(SettingsFile.KEY_STEREO_DEPTH);
-    Setting convergence = stereoScopySection.getSetting(SettingsFile.KEY_STEREO_CONV);
-    Setting swapEyes = stereoScopySection.getSetting(SettingsFile.KEY_STEREO_SWAP);
-
-    sl.add(new SingleChoiceSetting(SettingsFile.KEY_STEREO_MODE, Settings.SECTION_STEREOSCOPY,
-            R.string.stereoscopy_mode, 0,
-            R.array.stereoscopyEntries, R.array.stereoscopyValues, 0, stereoModeValue));
-    sl.add(new SliderSetting(SettingsFile.KEY_STEREO_DEPTH, Settings.SECTION_STEREOSCOPY,
-            R.string.stereoscopy_depth, R.string.stereoscopy_depth_description, 100, "%", 20,
-            stereoDepth));
-    sl.add(new SliderSetting(SettingsFile.KEY_STEREO_CONV, Settings.SECTION_STEREOSCOPY,
-            R.string.stereoscopy_convergence, R.string.stereoscopy_convergence_description, 200,
-            "%", 0, convergence));
-    sl.add(new CheckBoxSetting(SettingsFile.KEY_STEREO_SWAP, Settings.SECTION_STEREOSCOPY,
-            R.string.stereoscopy_swap_eyes, R.string.stereoscopy_swap_eyes_description, false,
-            swapEyes));
+    sl.add(new SingleChoiceSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_STEREOSCOPY,
+            SettingsFile.KEY_STEREO_MODE, R.string.stereoscopy_mode, 0,
+            R.array.stereoscopyEntries, R.array.stereoscopyValues, 0));
+    sl.add(new IntSliderSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_STEREOSCOPY,
+            SettingsFile.KEY_STEREO_DEPTH, R.string.stereoscopy_depth,
+            R.string.stereoscopy_depth_description, 100, "%", 20));
+    sl.add(new IntSliderSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_STEREOSCOPY,
+            SettingsFile.KEY_STEREO_CONV, R.string.stereoscopy_convergence,
+            R.string.stereoscopy_convergence_description, 200, "%", 0));
+    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_STEREOSCOPY,
+            SettingsFile.KEY_STEREO_SWAP, R.string.stereoscopy_swap_eyes,
+            R.string.stereoscopy_swap_eyes_description, false));
   }
 
   private void addGcPadSubSettings(ArrayList<SettingsItem> sl, int gcPadNumber, int gcPadType)
   {
-    SettingSection bindingsSection = mSettings.getSection(Settings.SECTION_BINDINGS);
-    SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
-
     if (gcPadType == 1) // Emulated
     {
-      Setting bindA = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_A + gcPadNumber);
-      Setting bindB = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_B + gcPadNumber);
-      Setting bindX = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_X + gcPadNumber);
-      Setting bindY = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_Y + gcPadNumber);
-      Setting bindZ = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_Z + gcPadNumber);
-      Setting bindStart = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_START + gcPadNumber);
-      Setting bindControlUp =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_CONTROL_UP + gcPadNumber);
-      Setting bindControlDown =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_CONTROL_DOWN + gcPadNumber);
-      Setting bindControlLeft =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_CONTROL_LEFT + gcPadNumber);
-      Setting bindControlRight =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_CONTROL_RIGHT + gcPadNumber);
-      Setting bindCUp = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_C_UP + gcPadNumber);
-      Setting bindCDown = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_C_DOWN + gcPadNumber);
-      Setting bindCLeft = bindingsSection.getSetting(SettingsFile.KEY_GCBIND_C_LEFT + gcPadNumber);
-      Setting bindCRight =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_C_RIGHT + gcPadNumber);
-      Setting bindTriggerL =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_TRIGGER_L + gcPadNumber);
-      Setting bindTriggerR =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_TRIGGER_R + gcPadNumber);
-      Setting bindDPadUp =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_DPAD_UP + gcPadNumber);
-      Setting bindDPadDown =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_DPAD_DOWN + gcPadNumber);
-      Setting bindDPadLeft =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_DPAD_LEFT + gcPadNumber);
-      Setting bindDPadRight =
-              bindingsSection.getSetting(SettingsFile.KEY_GCBIND_DPAD_RIGHT + gcPadNumber);
-      Setting gcEmuRumble =
-              bindingsSection.getSetting(SettingsFile.KEY_EMU_RUMBLE + gcPadNumber);
+      sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_A + gcPadNumber, R.string.button_a, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_B + gcPadNumber, R.string.button_b, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_X + gcPadNumber, R.string.button_x, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_Y + gcPadNumber, R.string.button_y, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_Z + gcPadNumber, R.string.button_z, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_START + gcPadNumber, R.string.button_start, mGameID));
 
-      sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_A + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.button_a, bindA, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_B + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.button_b, bindB, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_X + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.button_x, bindX, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_Y + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.button_y, bindY, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_Z + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.button_z, bindZ, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_START + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.button_start, bindStart, mGameID));
+      sl.add(new HeaderSetting(null, R.string.controller_control, 0));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_CONTROL_UP + gcPadNumber, R.string.generic_up, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_CONTROL_DOWN + gcPadNumber, R.string.generic_down, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_CONTROL_LEFT + gcPadNumber, R.string.generic_left, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_CONTROL_RIGHT + gcPadNumber, R.string.generic_right,
+              mGameID));
 
-      sl.add(new HeaderSetting(null, null, R.string.controller_control, 0));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_CONTROL_UP + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_up, bindControlUp, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_CONTROL_DOWN + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_down, bindControlDown, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_CONTROL_LEFT + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_left, bindControlLeft, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_CONTROL_RIGHT + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_right, bindControlRight, mGameID));
+      sl.add(new HeaderSetting(null, R.string.controller_c, 0));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_C_UP + gcPadNumber, R.string.generic_up, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_C_DOWN + gcPadNumber, R.string.generic_down, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_C_LEFT + gcPadNumber, R.string.generic_left, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_C_RIGHT + gcPadNumber, R.string.generic_right, mGameID));
 
-      sl.add(new HeaderSetting(null, null, R.string.controller_c, 0));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_C_UP + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_up, bindCUp, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_C_DOWN + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_down, bindCDown, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_C_LEFT + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_left, bindCLeft, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_C_RIGHT + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_right, bindCRight, mGameID));
+      sl.add(new HeaderSetting(null, R.string.controller_trig, 0));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_TRIGGER_L + gcPadNumber, R.string.trigger_left, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_TRIGGER_R + gcPadNumber, R.string.trigger_right, mGameID));
 
-      sl.add(new HeaderSetting(null, null, R.string.controller_trig, 0));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_TRIGGER_L + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.trigger_left, bindTriggerL, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_TRIGGER_R + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.trigger_right, bindTriggerR, mGameID));
-
-      sl.add(new HeaderSetting(null, null, R.string.controller_dpad, 0));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_DPAD_UP + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_up, bindDPadUp, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_DPAD_DOWN + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_down, bindDPadDown, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_DPAD_LEFT + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_left, bindDPadLeft, mGameID));
-      sl.add(new InputBindingSetting(SettingsFile.KEY_GCBIND_DPAD_RIGHT + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.generic_right, bindDPadRight, mGameID));
+      sl.add(new HeaderSetting(null, R.string.controller_dpad, 0));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_DPAD_UP + gcPadNumber, R.string.generic_up, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_DPAD_DOWN + gcPadNumber, R.string.generic_down, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_DPAD_LEFT + gcPadNumber, R.string.generic_left, mGameID));
+      sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_GCBIND_DPAD_RIGHT + gcPadNumber, R.string.generic_right, mGameID));
 
 
-      sl.add(new HeaderSetting(null, null, R.string.emulation_control_rumble, 0));
-      sl.add(new RumbleBindingSetting(SettingsFile.KEY_EMU_RUMBLE + gcPadNumber,
-              Settings.SECTION_BINDINGS, R.string.emulation_control_rumble, gcEmuRumble, mGameID));
+      sl.add(new HeaderSetting(null, R.string.emulation_control_rumble, 0));
+      sl.add(new RumbleBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+              SettingsFile.KEY_EMU_RUMBLE + gcPadNumber, R.string.emulation_control_rumble,
+              mGameID));
     }
     else // Adapter
     {
-      Setting rumble = coreSection.getSetting(SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber);
-      Setting bongos = coreSection.getSetting(SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber);
-
-      sl.add(new CheckBoxSetting(SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber,
-              Settings.SECTION_INI_CORE, R.string.gc_adapter_rumble,
-              R.string.gc_adapter_rumble_description, false, rumble));
-      sl.add(new CheckBoxSetting(SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber,
-              Settings.SECTION_INI_CORE, R.string.gc_adapter_bongos,
-              R.string.gc_adapter_bongos_description, false, bongos));
+      sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+              SettingsFile.KEY_GCADAPTER_RUMBLE + gcPadNumber, R.string.gc_adapter_rumble,
+              R.string.gc_adapter_rumble_description, false));
+      sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+              SettingsFile.KEY_GCADAPTER_BONGOS + gcPadNumber, R.string.gc_adapter_bongos,
+              R.string.gc_adapter_bongos_description, false));
     }
   }
 
   private void addWiimoteSubSettings(ArrayList<SettingsItem> sl, int wiimoteNumber)
   {
-    SettingSection bindingsSection = mSettings.getSection(Settings.SECTION_BINDINGS);
-
-
-    Setting bindA = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_A + wiimoteNumber);
-    Setting bindB = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_B + wiimoteNumber);
-    Setting bind1 = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_1 + wiimoteNumber);
-    Setting bind2 = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_2 + wiimoteNumber);
-    Setting bindMinus = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_MINUS + wiimoteNumber);
-    Setting bindPlus = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_PLUS + wiimoteNumber);
-    Setting bindHome = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_HOME + wiimoteNumber);
-    Setting bindIRUp = bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_UP + wiimoteNumber);
-    Setting bindIRDown =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_DOWN + wiimoteNumber);
-    Setting bindIRLeft =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_LEFT + wiimoteNumber);
-    Setting bindIRRight =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_RIGHT + wiimoteNumber);
-    Setting bindIRForward =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_FORWARD + wiimoteNumber);
-    Setting bindIRBackward =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_BACKWARD + wiimoteNumber);
-    Setting bindIRHide =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_IR_HIDE + wiimoteNumber);
-    Setting bindSwingUp =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SWING_UP + wiimoteNumber);
-    Setting bindSwingDown =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SWING_DOWN + wiimoteNumber);
-    Setting bindSwingLeft =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SWING_LEFT + wiimoteNumber);
-    Setting bindSwingRight =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SWING_RIGHT + wiimoteNumber);
-    Setting bindSwingForward =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SWING_FORWARD + wiimoteNumber);
-    Setting bindSwingBackward =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SWING_BACKWARD + wiimoteNumber);
-    Setting bindTiltForward =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_TILT_FORWARD + wiimoteNumber);
-    Setting bindTiltBackward =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_TILT_BACKWARD + wiimoteNumber);
-    Setting bindTiltLeft =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_TILT_LEFT + wiimoteNumber);
-    Setting bindTiltRight =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_TILT_RIGHT + wiimoteNumber);
-    Setting bindTiltModifier =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_TILT_MODIFIER + wiimoteNumber);
-    Setting bindShakeX =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SHAKE_X + wiimoteNumber);
-    Setting bindShakeY =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SHAKE_Y + wiimoteNumber);
-    Setting bindShakeZ =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_SHAKE_Z + wiimoteNumber);
-    Setting bindDPadUp =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DPAD_UP + wiimoteNumber);
-    Setting bindDPadDown =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DPAD_DOWN + wiimoteNumber);
-    Setting bindDPadLeft =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DPAD_LEFT + wiimoteNumber);
-    Setting bindDPadRight =
-            bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DPAD_RIGHT + wiimoteNumber);
-    Setting wiiEmuRumble =
-            bindingsSection.getSetting(SettingsFile.KEY_EMU_RUMBLE + wiimoteNumber);
-
     // Bindings use controller numbers 4-7 (0-3 are GameCube), but the extension setting uses 1-4.
     // But game game specific extension settings are saved in their own profile. These profiles
     // do not have any way to specify the controller that is loaded outside of knowing the filename
     // of the profile that was loaded.
-    Setting extension;
-    if (mGameID.equals(""))
+    if (mGameID.isEmpty())
     {
-      extension = mSettings.getSection(Settings.SECTION_WIIMOTE + (wiimoteNumber - 3)).
-              getSetting(SettingsFile.KEY_WIIMOTE_EXTENSION);
-      sl.add(new StringSingleChoiceSetting(SettingsFile.KEY_WIIMOTE_EXTENSION,
-              Settings.SECTION_WIIMOTE + (wiimoteNumber - 3), R.string.wiimote_extensions,
-              0, R.array.wiimoteExtensionsEntries,
-              R.array.wiimoteExtensionsValues, getExtensionValue(wiimoteNumber - 3), extension,
+      sl.add(new StringSingleChoiceSetting(SettingsFile.FILE_NAME_WIIMOTE,
+              Settings.SECTION_WIIMOTE + (wiimoteNumber - 3), SettingsFile.KEY_WIIMOTE_EXTENSION,
+              R.string.wiimote_extensions, 0, R.array.wiimoteExtensionsEntries,
+              R.array.wiimoteExtensionsValues, getExtensionValue(wiimoteNumber - 3),
               MenuTag.getWiimoteExtensionMenuTag(wiimoteNumber)));
     }
     else
     {
-      mSettings.loadWiimoteProfile(mGameID, String.valueOf(wiimoteNumber - 4));
-      extension = mSettings.getSection(Settings.SECTION_CONTROLS).
-              getSetting(SettingsFile.KEY_WIIMOTE_EXTENSION + (wiimoteNumber - 4));
-      sl.add(new StringSingleChoiceSetting(SettingsFile.KEY_WIIMOTE_EXTENSION + (wiimoteNumber - 4),
-              Settings.SECTION_CONTROLS, R.string.wiimote_extensions,
-              0, R.array.wiimoteExtensionsEntries,
-              R.array.wiimoteExtensionsValues, getExtensionValue(wiimoteNumber - 4), extension,
+      mSettings.loadWiimoteProfile(mGameID, wiimoteNumber - 4);
+      sl.add(new StringSingleChoiceSetting(Settings.GAME_SETTINGS_PLACEHOLDER_FILE_NAME,
+              Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIMOTE_EXTENSION + (wiimoteNumber - 4),
+              R.string.wiimote_extensions, 0, R.array.wiimoteExtensionsEntries,
+              R.array.wiimoteExtensionsValues, getExtensionValue(wiimoteNumber - 4),
               MenuTag.getWiimoteExtensionMenuTag(wiimoteNumber)));
     }
 
-    sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_A + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_a, bindA, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_B + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_b, bindB, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_1 + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_one, bind1, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_2 + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_two, bind2, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_MINUS + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_minus, bindMinus, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_PLUS + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_plus, bindPlus, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_HOME + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.button_home, bindHome, mGameID));
+    sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_A + wiimoteNumber, R.string.button_a, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_B + wiimoteNumber, R.string.button_b, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_1 + wiimoteNumber, R.string.button_one, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_2 + wiimoteNumber, R.string.button_two, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_MINUS + wiimoteNumber, R.string.button_minus, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_PLUS + wiimoteNumber, R.string.button_plus, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_HOME + wiimoteNumber, R.string.button_home, mGameID));
 
-    sl.add(new HeaderSetting(null, null, R.string.wiimote_ir, 0));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_UP + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_up, bindIRUp, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_DOWN + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_down, bindIRDown, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_LEFT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_left, bindIRLeft, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_RIGHT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_right, bindIRRight, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_FORWARD + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_forward, bindIRForward, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_BACKWARD + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_backward, bindIRBackward, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_IR_HIDE + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.ir_hide, bindIRHide, mGameID));
+    sl.add(new HeaderSetting(null, R.string.wiimote_ir, 0));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_UP + wiimoteNumber, R.string.generic_up, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_DOWN + wiimoteNumber, R.string.generic_down, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_LEFT + wiimoteNumber, R.string.generic_left, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_RIGHT + wiimoteNumber, R.string.generic_right, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_FORWARD + wiimoteNumber, R.string.generic_forward,
+            mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_BACKWARD + wiimoteNumber, R.string.generic_backward,
+            mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_IR_HIDE + wiimoteNumber, R.string.ir_hide, mGameID));
 
-    sl.add(new HeaderSetting(null, null, R.string.wiimote_swing, 0));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SWING_UP + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_up, bindSwingUp, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SWING_DOWN + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_down, bindSwingDown, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SWING_LEFT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_left, bindSwingLeft, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SWING_RIGHT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_right, bindSwingRight, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SWING_FORWARD + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_forward, bindSwingForward, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SWING_BACKWARD + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_backward, bindSwingBackward, mGameID));
+    sl.add(new HeaderSetting(null, R.string.wiimote_swing, 0));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SWING_UP + wiimoteNumber, R.string.generic_up, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SWING_DOWN + wiimoteNumber, R.string.generic_down, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SWING_LEFT + wiimoteNumber, R.string.generic_left, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SWING_RIGHT + wiimoteNumber, R.string.generic_right, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SWING_FORWARD + wiimoteNumber, R.string.generic_forward,
+            mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SWING_BACKWARD + wiimoteNumber, R.string.generic_backward,
+            mGameID));
 
-    sl.add(new HeaderSetting(null, null, R.string.wiimote_tilt, 0));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TILT_FORWARD + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_forward, bindTiltForward, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TILT_BACKWARD + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_backward, bindTiltBackward, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TILT_LEFT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_left, bindTiltLeft, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TILT_RIGHT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_right, bindTiltRight, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TILT_MODIFIER + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.tilt_modifier, bindTiltModifier, mGameID));
+    sl.add(new HeaderSetting(null, R.string.wiimote_tilt, 0));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_TILT_FORWARD + wiimoteNumber, R.string.generic_forward,
+            mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_TILT_BACKWARD + wiimoteNumber, R.string.generic_backward,
+            mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_TILT_LEFT + wiimoteNumber, R.string.generic_left, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_TILT_RIGHT + wiimoteNumber, R.string.generic_right, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_TILT_MODIFIER + wiimoteNumber, R.string.tilt_modifier,
+            mGameID));
 
-    sl.add(new HeaderSetting(null, null, R.string.wiimote_shake, 0));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SHAKE_X + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.shake_x, bindShakeX, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SHAKE_Y + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.shake_y, bindShakeY, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_SHAKE_Z + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.shake_z, bindShakeZ, mGameID));
+    sl.add(new HeaderSetting(null, R.string.wiimote_shake, 0));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SHAKE_X + wiimoteNumber, R.string.shake_x, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SHAKE_Y + wiimoteNumber, R.string.shake_y, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_SHAKE_Z + wiimoteNumber, R.string.shake_z, mGameID));
 
-    sl.add(new HeaderSetting(null, null, R.string.controller_dpad, 0));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DPAD_UP + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_up, bindDPadUp, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DPAD_DOWN + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_down, bindDPadDown, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DPAD_LEFT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_left, bindDPadLeft, mGameID));
-    sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DPAD_RIGHT + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.generic_right, bindDPadRight, mGameID));
+    sl.add(new HeaderSetting(null, R.string.controller_dpad, 0));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_DPAD_UP + wiimoteNumber, R.string.generic_up, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_DPAD_DOWN + wiimoteNumber, R.string.generic_down, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_DPAD_LEFT + wiimoteNumber, R.string.generic_left, mGameID));
+    sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_WIIBIND_DPAD_RIGHT + wiimoteNumber, R.string.generic_right, mGameID));
 
 
-    sl.add(new HeaderSetting(null, null, R.string.emulation_control_rumble, 0));
-    sl.add(new RumbleBindingSetting(SettingsFile.KEY_EMU_RUMBLE + wiimoteNumber,
-            Settings.SECTION_BINDINGS, R.string.emulation_control_rumble, wiiEmuRumble, mGameID));
+    sl.add(new HeaderSetting(null, R.string.emulation_control_rumble, 0));
+    sl.add(new RumbleBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+            SettingsFile.KEY_EMU_RUMBLE + wiimoteNumber, R.string.emulation_control_rumble,
+            mGameID));
   }
 
   private void addExtensionTypeSettings(ArrayList<SettingsItem> sl, int wiimoteNumber,
           int extentionType)
   {
-    SettingSection bindingsSection = mSettings.getSection(Settings.SECTION_BINDINGS);
-
     switch (extentionType)
     {
       case 1: // Nunchuk
-        Setting bindC =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_C + wiimoteNumber);
-        Setting bindZ =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_Z + wiimoteNumber);
-        Setting bindUp =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_UP + wiimoteNumber);
-        Setting bindDown =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_DOWN + wiimoteNumber);
-        Setting bindLeft =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_LEFT + wiimoteNumber);
-        Setting bindRight =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_RIGHT + wiimoteNumber);
-        Setting bindSwingUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_UP + wiimoteNumber);
-        Setting bindSwingDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_DOWN + wiimoteNumber);
-        Setting bindSwingLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_LEFT + wiimoteNumber);
-        Setting bindSwingRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_RIGHT + wiimoteNumber);
-        Setting bindSwingForward = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_FORWARD + wiimoteNumber);
-        Setting bindSwingBackward = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_BACKWARD + wiimoteNumber);
-        Setting bindTiltForward = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_FORWARD + wiimoteNumber);
-        Setting bindTiltBackward = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_BACKWARD + wiimoteNumber);
-        Setting bindTiltLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_LEFT + wiimoteNumber);
-        Setting bindTiltRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_RIGHT + wiimoteNumber);
-        Setting bindTiltModifier = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_MODIFIER + wiimoteNumber);
-        Setting bindShakeX = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_X + wiimoteNumber);
-        Setting bindShakeY = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_Y + wiimoteNumber);
-        Setting bindShakeZ = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_Z + wiimoteNumber);
+        sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_C + wiimoteNumber, R.string.nunchuk_button_c,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_Z + wiimoteNumber, R.string.button_z, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_C + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.nunchuk_button_c, bindC, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_Z + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_z, bindZ, mGameID));
+        sl.add(new HeaderSetting(null, R.string.generic_stick, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_UP + wiimoteNumber, R.string.generic_up, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_RIGHT + wiimoteNumber, R.string.generic_right,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_stick, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindRight, mGameID));
-
-        sl.add(new HeaderSetting(null, null, R.string.wiimote_swing, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindSwingUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindSwingDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindSwingLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindSwingRight, mGameID));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.wiimote_swing, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_RIGHT + wiimoteNumber,
+                R.string.generic_right, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_FORWARD + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_forward, bindSwingForward, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_forward, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_NUNCHUK_SWING_BACKWARD + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_backward, bindSwingBackward, mGameID));
+                R.string.generic_backward, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.wiimote_tilt, 0));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.wiimote_tilt, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_FORWARD + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_forward, bindTiltForward, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_forward, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_BACKWARD + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_backward, bindTiltBackward, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindTiltLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindTiltRight, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_backward, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_RIGHT + wiimoteNumber, R.string.generic_right,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_NUNCHUK_TILT_MODIFIER + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.tilt_modifier, bindTiltModifier, mGameID));
+                R.string.tilt_modifier, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.wiimote_shake, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_X + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.shake_x, bindShakeX, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_Y + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.shake_y, bindShakeY, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_Z + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.shake_z, bindShakeZ, mGameID));
+        sl.add(new HeaderSetting(null, R.string.wiimote_shake, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_X + wiimoteNumber, R.string.shake_x,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_Y + wiimoteNumber, R.string.shake_y,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_NUNCHUK_SHAKE_Z + wiimoteNumber, R.string.shake_z,
+                mGameID));
         break;
       case 2: // Classic
-        Setting bindA =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_A + wiimoteNumber);
-        Setting bindB =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_B + wiimoteNumber);
-        Setting bindX =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_X + wiimoteNumber);
-        Setting bindY =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_Y + wiimoteNumber);
-        Setting bindZL =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_ZL + wiimoteNumber);
-        Setting bindZR =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_ZR + wiimoteNumber);
-        Setting bindMinus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_MINUS + wiimoteNumber);
-        Setting bindPlus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_PLUS + wiimoteNumber);
-        Setting bindHome =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_HOME + wiimoteNumber);
-        Setting bindLeftUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_UP + wiimoteNumber);
-        Setting bindLeftDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_DOWN + wiimoteNumber);
-        Setting bindLeftLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_LEFT + wiimoteNumber);
-        Setting bindLeftRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_RIGHT + wiimoteNumber);
-        Setting bindRightUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_UP + wiimoteNumber);
-        Setting bindRightDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_DOWN + wiimoteNumber);
-        Setting bindRightLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_LEFT + wiimoteNumber);
-        Setting bindRightRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_RIGHT + wiimoteNumber);
-        Setting bindL = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_TRIGGER_L + wiimoteNumber);
-        Setting bindR = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_TRIGGER_R + wiimoteNumber);
-        Setting bindDpadUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_UP + wiimoteNumber);
-        Setting bindDpadDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_DOWN + wiimoteNumber);
-        Setting bindDpadLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_LEFT + wiimoteNumber);
-        Setting bindDpadRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_RIGHT + wiimoteNumber);
+        sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_A + wiimoteNumber, R.string.button_a, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_B + wiimoteNumber, R.string.button_b, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_X + wiimoteNumber, R.string.button_x, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_Y + wiimoteNumber, R.string.button_y, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_ZL + wiimoteNumber, R.string.classic_button_zl,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_ZR + wiimoteNumber, R.string.classic_button_zr,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_MINUS + wiimoteNumber, R.string.button_minus,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_PLUS + wiimoteNumber, R.string.button_plus,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_HOME + wiimoteNumber, R.string.button_home,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_A + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_a, bindA, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_B + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_b, bindB, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_X + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_x, bindX, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_Y + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_y, bindY, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_ZL + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.classic_button_zl, bindZL, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_ZR + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.classic_button_zr, bindZR, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_MINUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_minus, bindMinus, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_PLUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_plus, bindPlus, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_HOME + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_home, bindHome, mGameID));
+        sl.add(new HeaderSetting(null, R.string.classic_leftstick, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_RIGHT + wiimoteNumber, R.string.generic_right,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.classic_leftstick, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindLeftUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindLeftDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindLeftLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_LEFT_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindLeftRight, mGameID));
+        sl.add(new HeaderSetting(null, R.string.classic_rightstick, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_RIGHT + wiimoteNumber,
+                R.string.generic_right, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.classic_rightstick, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindRightUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindRightDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindRightLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_RIGHT_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindRightRight, mGameID));
+        sl.add(new HeaderSetting(null, R.string.controller_trig, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_TRIGGER_L + wiimoteNumber, R.string.trigger_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_TRIGGER_R + wiimoteNumber, R.string.trigger_right,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.controller_trig, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_TRIGGER_L + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.trigger_left, bindR, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_TRIGGER_R + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.trigger_right, bindL, mGameID));
-
-        sl.add(new HeaderSetting(null, null, R.string.controller_dpad, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindDpadUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindDpadDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindDpadLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindDpadRight, mGameID));
+        sl.add(new HeaderSetting(null, R.string.controller_dpad, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_CLASSIC_DPAD_RIGHT + wiimoteNumber, R.string.generic_right,
+                mGameID));
         break;
       case 3: // Guitar
-        Setting bindFretGreen = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_GREEN + wiimoteNumber);
-        Setting bindFretRed = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_RED + wiimoteNumber);
-        Setting bindFretYellow = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_YELLOW + wiimoteNumber);
-        Setting bindFretBlue = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_BLUE + wiimoteNumber);
-        Setting bindFretOrange = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_ORANGE + wiimoteNumber);
-        Setting bindStrumUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_STRUM_UP + wiimoteNumber);
-        Setting bindStrumDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_STRUM_DOWN + wiimoteNumber);
-        Setting bindGuitarMinus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_GUITAR_MINUS + wiimoteNumber);
-        Setting bindGuitarPlus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_GUITAR_PLUS + wiimoteNumber);
-        Setting bindGuitarUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_UP + wiimoteNumber);
-        Setting bindGuitarDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_DOWN + wiimoteNumber);
-        Setting bindGuitarLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_LEFT + wiimoteNumber);
-        Setting bindGuitarRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_RIGHT + wiimoteNumber);
-        Setting bindWhammyBar = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_GUITAR_WHAMMY_BAR + wiimoteNumber);
+        sl.add(new HeaderSetting(null, R.string.guitar_frets, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_FRET_GREEN + wiimoteNumber, R.string.generic_green,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_FRET_RED + wiimoteNumber, R.string.generic_red,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_FRET_YELLOW + wiimoteNumber,
+                R.string.generic_yellow, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_FRET_BLUE + wiimoteNumber, R.string.generic_blue,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_FRET_ORANGE + wiimoteNumber,
+                R.string.generic_orange, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.guitar_frets, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_GREEN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_green, bindFretGreen, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_RED + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_red, bindFretRed, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_YELLOW + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_yellow, bindFretYellow, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_BLUE + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_blue, bindFretBlue, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_FRET_ORANGE + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_orange, bindFretOrange, mGameID));
+        sl.add(new HeaderSetting(null, R.string.guitar_strum, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_STRUM_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_STRUM_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.guitar_strum, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_STRUM_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindStrumUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_STRUM_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindStrumDown, mGameID));
+        sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_MINUS + wiimoteNumber, R.string.button_minus,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_PLUS + wiimoteNumber, R.string.button_plus,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_MINUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_minus, bindGuitarMinus, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_PLUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_plus, bindGuitarPlus, mGameID));
+        sl.add(new HeaderSetting(null, R.string.generic_stick, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_STICK_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_STICK_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_STICK_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_STICK_RIGHT + wiimoteNumber, R.string.generic_right,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_stick, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindGuitarUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindGuitarDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindGuitarLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_STICK_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindGuitarRight, mGameID));
-
-        sl.add(new HeaderSetting(null, null, R.string.guitar_whammy, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_GUITAR_WHAMMY_BAR + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindWhammyBar, mGameID));
+        sl.add(new HeaderSetting(null, R.string.guitar_whammy, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_GUITAR_WHAMMY_BAR + wiimoteNumber, R.string.generic_right,
+                mGameID));
         break;
       case 4: // Drums
-        Setting bindPadRed =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_RED + wiimoteNumber);
-        Setting bindPadYellow = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_YELLOW + wiimoteNumber);
-        Setting bindPadBlue =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_BLUE + wiimoteNumber);
-        Setting bindPadGreen = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_GREEN + wiimoteNumber);
-        Setting bindPadOrange = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_ORANGE + wiimoteNumber);
-        Setting bindPadBass =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_BASS + wiimoteNumber);
-        Setting bindDrumsUp =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_UP + wiimoteNumber);
-        Setting bindDrumsDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_DOWN + wiimoteNumber);
-        Setting bindDrumsLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_LEFT + wiimoteNumber);
-        Setting bindDrumsRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_RIGHT + wiimoteNumber);
-        Setting bindDrumsMinus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DRUMS_MINUS + wiimoteNumber);
-        Setting bindDrumsPlus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_DRUMS_PLUS + wiimoteNumber);
+        sl.add(new HeaderSetting(null, R.string.drums_pads, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PAD_RED + wiimoteNumber, R.string.generic_red,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PAD_YELLOW + wiimoteNumber, R.string.generic_yellow,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PAD_BLUE + wiimoteNumber, R.string.generic_blue,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PAD_GREEN + wiimoteNumber, R.string.generic_green,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PAD_ORANGE + wiimoteNumber, R.string.generic_orange,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PAD_BASS + wiimoteNumber, R.string.drums_pad_bass,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.drums_pads, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_RED + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_red, bindPadRed, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_YELLOW + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_yellow, bindPadYellow, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_BLUE + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_blue, bindPadBlue, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_GREEN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_green, bindPadGreen, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_ORANGE + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_orange, bindPadOrange, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PAD_BASS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.drums_pad_bass, bindPadBass, mGameID));
+        sl.add(new HeaderSetting(null, R.string.generic_stick, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_STICK_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_STICK_DOWN + wiimoteNumber, R.string.generic_down,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_STICK_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_STICK_RIGHT + wiimoteNumber, R.string.generic_right,
+                mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_stick, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindDrumsUp, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindDrumsDown, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindDrumsLeft, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_STICK_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindDrumsRight, mGameID));
-
-        sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_MINUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_minus, bindDrumsMinus, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_DRUMS_PLUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_plus, bindDrumsPlus, mGameID));
+        sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_MINUS + wiimoteNumber, R.string.button_minus,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_DRUMS_PLUS + wiimoteNumber, R.string.button_plus,
+                mGameID));
         break;
       case 5: // Turntable
-        Setting bindGreenLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_GREEN_LEFT + wiimoteNumber);
-        Setting bindRedLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_RED_LEFT + wiimoteNumber);
-        Setting bindBlueLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_BLUE_LEFT + wiimoteNumber);
-        Setting bindGreenRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_GREEN_RIGHT + wiimoteNumber);
-        Setting bindRedRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_RED_RIGHT + wiimoteNumber);
-        Setting bindBlueRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_BLUE_RIGHT + wiimoteNumber);
-        Setting bindTurntableMinus = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_MINUS + wiimoteNumber);
-        Setting bindTurntablePlus =
-                bindingsSection.getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_PLUS + wiimoteNumber);
-        Setting bindEuphoria = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_EUPHORIA + wiimoteNumber);
-        Setting bindTurntableLeftLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_LEFT_LEFT + wiimoteNumber);
-        Setting bindTurntableLeftRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_LEFT_RIGHT + wiimoteNumber);
-        Setting bindTurntableRightLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_RIGHT_LEFT + wiimoteNumber);
-        Setting bindTurntableRightRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_RIGHT_RIGHT + wiimoteNumber);
-        Setting bindTurntableUp = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_UP + wiimoteNumber);
-        Setting bindTurntableDown = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_DOWN + wiimoteNumber);
-        Setting bindTurntableLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_LEFT + wiimoteNumber);
-        Setting bindTurntableRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_RIGHT + wiimoteNumber);
-        Setting bindEffectDial = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_EFFECT_DIAL + wiimoteNumber);
-        Setting bindCrossfadeLeft = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_CROSSFADE_LEFT + wiimoteNumber);
-        Setting bindCrossfadeRight = bindingsSection
-                .getSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_CROSSFADE_RIGHT + wiimoteNumber);
-
-        sl.add(new HeaderSetting(null, null, R.string.generic_buttons, 0));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.generic_buttons, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_GREEN_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_green_left, bindGreenLeft,
-                mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_RED_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_red_left, bindRedLeft,
-                mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_BLUE_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_blue_left, bindBlueLeft,
-                mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.turntable_button_green_left, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_RED_LEFT + wiimoteNumber,
+                R.string.turntable_button_red_left, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_BLUE_LEFT + wiimoteNumber,
+                R.string.turntable_button_blue_left, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_GREEN_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_green_right, bindGreenRight,
-                mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_RED_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_red_right, bindRedRight,
-                mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.turntable_button_green_right, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_RED_RIGHT + wiimoteNumber,
+                R.string.turntable_button_red_right, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_BLUE_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_blue_right, bindBlueRight,
-                mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_MINUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_minus, bindTurntableMinus, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_PLUS + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.button_plus, bindTurntablePlus, mGameID));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_EUPHORIA + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_button_euphoria, bindEuphoria,
-                mGameID));
+                R.string.turntable_button_blue_right, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_MINUS + wiimoteNumber,
+                R.string.button_minus, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_PLUS + wiimoteNumber,
+                R.string.button_plus, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_EUPHORIA + wiimoteNumber,
+                R.string.turntable_button_euphoria, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.turntable_table_left, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_LEFT_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindTurntableLeftLeft, mGameID));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.turntable_table_left, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_LEFT_LEFT + wiimoteNumber, R.string.generic_left,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_LEFT_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindTurntableLeftRight,
-                mGameID));
+                R.string.generic_right, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.turntable_table_right, 0));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.turntable_table_right, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_RIGHT_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindTurntableRightLeft, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_left, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_RIGHT_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindTurntableRightRight,
-                mGameID));
+                R.string.generic_right, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.generic_stick, 0));
-        sl.add(new InputBindingSetting(SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_UP + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_up, bindTurntableUp, mGameID));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.generic_stick, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
+                SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_UP + wiimoteNumber, R.string.generic_up,
+                mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_DOWN + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_down, bindTurntableDown, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_down, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindTurntableLeft, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_left, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_STICK_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindTurntableRight, mGameID));
+                R.string.generic_right, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.turntable_effect, 0));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.turntable_effect, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_EFFECT_DIAL + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.turntable_effect_dial, bindEffectDial,
-                mGameID));
+                R.string.turntable_effect_dial, mGameID));
 
-        sl.add(new HeaderSetting(null, null, R.string.turntable_crossfade, 0));
-        sl.add(new InputBindingSetting(
+        sl.add(new HeaderSetting(null, R.string.turntable_crossfade, 0));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_CROSSFADE_LEFT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_left, bindCrossfadeLeft, mGameID));
-        sl.add(new InputBindingSetting(
+                R.string.generic_left, mGameID));
+        sl.add(new InputBindingSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS,
                 SettingsFile.KEY_WIIBIND_TURNTABLE_CROSSFADE_RIGHT + wiimoteNumber,
-                Settings.SECTION_BINDINGS, R.string.generic_right, bindCrossfadeRight, mGameID));
+                R.string.generic_right, mGameID));
         break;
     }
   }
 
-  private boolean getInvertedBooleanValue(String section, String key, boolean defaultValue)
-  {
-    try
-    {
-      return !((BooleanSetting) mSettings.getSection(section).getSetting(key)).getValue();
-    }
-    catch (NullPointerException ex)
-    {
-      return defaultValue;
-    }
-  }
-
   private String getExtensionValue(int wiimoteNumber)
   {
-    try
+    IniFile.Section section;
+    if (mGameID.equals("")) // Main settings
     {
-      if (mGameID.equals("")) // Main settings
-      {
-        return ((StringSetting) mSettings.getSection(Settings.SECTION_WIIMOTE + wiimoteNumber)
-                .getSetting(SettingsFile.KEY_WIIMOTE_EXTENSION)).getValue();
-      }
-      else // Game settings
-      {
-        return ((StringSetting) mSettings.getSection(Settings.SECTION_PROFILE)
-                .getSetting(SettingsFile.KEY_WIIMOTE_EXTENSION)).getValue();
-      }
+      section = mSettings.getSection(SettingsFile.FILE_NAME_WIIMOTE,
+              Settings.SECTION_WIIMOTE + wiimoteNumber);
     }
-    catch (NullPointerException ex)
+    else // Game settings
     {
-      return "None";
+      section = mSettings.getSection(Settings.GAME_SETTINGS_PLACEHOLDER_FILE_NAME,
+              Settings.SECTION_PROFILE);
     }
+    return section.getString(SettingsFile.KEY_WIIMOTE_EXTENSION, "None");
   }
 
   public static String getDefaultNANDRootPath()
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.java
index 7c976535b2..4951164a5b 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentView.java
@@ -2,7 +2,6 @@ package org.dolphinemu.dolphinemu.features.settings.ui;
 
 import androidx.fragment.app.FragmentActivity;
 
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 
@@ -23,9 +22,9 @@ public interface SettingsFragmentView
   void onSettingsFileLoaded(Settings settings);
 
   /**
-   * Pass an ArrayList to the View so that it can be displayed on screen.
+   * Pass an ArrayList of settings to the View so that it can be displayed on screen.
    *
-   * @param settingsList The result of converting the HashMap to an ArrayList
+   * @param settingsList The settings to display
    */
   void showSettingsList(ArrayList<SettingsItem> settingsList);
 
@@ -61,11 +60,9 @@ public interface SettingsFragmentView
   void showToastMessage(String message);
 
   /**
-   * Have the fragment add a setting to the HashMap.
-   *
-   * @param setting The (possibly previously missing) new setting.
+   * @return The backing settings store.
    */
-  void putSetting(Setting setting);
+  Settings getSettings();
 
   /**
    * Have the fragment tell the containing Activity that a setting was modified.
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java
index 0e0414bdaa..e7103632c6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/CheckBoxSettingViewHolder.java
@@ -57,7 +57,7 @@ public final class CheckBoxSettingViewHolder extends SettingViewHolder
       mTextSettingDescription.setText("");
     }
 
-    mCheckbox.setChecked(mItem.isChecked());
+    mCheckbox.setChecked(mItem.isChecked(getAdapter().getSettings()));
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java
index 01b0f7551b..e47c40248f 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/FilePickerViewHolder.java
@@ -7,6 +7,7 @@ import org.dolphinemu.dolphinemu.R;
 import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
+import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
 import org.dolphinemu.dolphinemu.utils.IniFile;
 
@@ -45,9 +46,9 @@ public final class FilePickerViewHolder extends SettingViewHolder
     else
     {
       // TODO: Reopening INI files all the time is slow
-      IniFile ini = new IniFile(mFilePicker.getFile());
+      IniFile ini = new IniFile(SettingsFile.getSettingsFile(mFilePicker.getFile()));
       mTextSettingDescription.setText(ini.getString(item.getSection(), item.getKey(),
-              mFilePicker.getSelectedValue()));
+              mFilePicker.getSelectedValue(getAdapter().getSettings())));
     }
   }
 
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java
index ed75d8928c..f0f85a0755 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SingleChoiceViewHolder.java
@@ -44,7 +44,7 @@ public final class SingleChoiceViewHolder extends SettingViewHolder
     else if (item instanceof SingleChoiceSetting)
     {
       SingleChoiceSetting setting = (SingleChoiceSetting) item;
-      int selected = setting.getSelectedValue();
+      int selected = setting.getSelectedValue(getAdapter().getSettings());
       Resources resMgr = mTextSettingDescription.getContext().getResources();
       String[] choices = resMgr.getStringArray(setting.getChoicesId());
       int[] values = resMgr.getIntArray(setting.getValuesId());
@@ -60,7 +60,7 @@ public final class SingleChoiceViewHolder extends SettingViewHolder
     {
       StringSingleChoiceSetting setting = (StringSingleChoiceSetting) item;
       String[] choices = setting.getChoicesId();
-      int valueIndex = setting.getSelectValueIndex();
+      int valueIndex = setting.getSelectValueIndex(getAdapter().getSettings());
       if (valueIndex != -1)
         mTextSettingDescription.setText(choices[valueIndex]);
     }
@@ -68,7 +68,7 @@ public final class SingleChoiceViewHolder extends SettingViewHolder
     {
       SingleChoiceSettingDynamicDescriptions setting =
               (SingleChoiceSettingDynamicDescriptions) item;
-      int selected = setting.getSelectedValue();
+      int selected = setting.getSelectedValue(getAdapter().getSettings());
       Resources resMgr = mTextSettingDescription.getContext().getResources();
       String[] choices = resMgr.getStringArray(setting.getDescriptionChoicesId());
       int[] values = resMgr.getIntArray(setting.getDescriptionValuesId());
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java
index 4e2967374a..ef359edb72 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SliderViewHolder.java
@@ -46,8 +46,8 @@ public final class SliderViewHolder extends SettingViewHolder
     else
     {
       mTextSettingDescription.setText(mContext
-              .getString(R.string.slider_setting_value, mItem.getSelectedValue(),
-                      mItem.getUnits()));
+              .getString(R.string.slider_setting_value,
+                      mItem.getSelectedValue(getAdapter().getSettings()), mItem.getUnits()));
     }
   }
 
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
index 78d7541288..80fc9001fb 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java
@@ -2,33 +2,14 @@ package org.dolphinemu.dolphinemu.features.settings.utils;
 
 import androidx.annotation.NonNull;
 
-import android.text.TextUtils;
-
-import org.dolphinemu.dolphinemu.NativeLibrary;
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.FloatSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
-import org.dolphinemu.dolphinemu.features.settings.model.Setting;
-import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
 import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView;
 import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
 import org.dolphinemu.dolphinemu.utils.BiMap;
 import org.dolphinemu.dolphinemu.utils.IniFile;
 import org.dolphinemu.dolphinemu.utils.Log;
 
-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 java.util.TreeMap;
-import java.util.TreeSet;
 
 /**
  * Contains static methods for interacting with .ini files in which settings are stored.
@@ -308,196 +289,103 @@ public final class SettingsFile
   }
 
   /**
-   * Reads a given .ini file from disk and returns it as a HashMap of Settings, themselves
-   * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
-   * failed.
+   * Reads a given .ini file from disk and returns it.
+   * If unsuccessful, outputs an error telling why it failed.
    *
-   * @param ini  The ini file to load the settings from
+   * @param file The ini file to load the settings from
+   * @param ini  The object to load into
    * @param view The current view.
    */
-  static HashMap<String, SettingSection> readFile(final File ini, boolean isCustomGame,
-          SettingsActivityView view)
+  static void readFile(final File file, IniFile ini, SettingsActivityView view)
   {
-    HashMap<String, SettingSection> sections = new Settings.SettingsSectionMap();
-
-    BufferedReader reader = null;
-
-    try
+    if (!ini.load(file, true))
     {
-      reader = new BufferedReader(new FileReader(ini));
-
-      SettingSection current = null;
-      for (String line; (line = reader.readLine()) != null; )
-      {
-        if (line.startsWith("[") && line.endsWith("]"))
-        {
-          current = sectionFromLine(line, isCustomGame);
-          sections.put(current.getName(), current);
-        }
-        else if ((current != null))
-        {
-          Setting setting = settingFromLine(current, line);
-          if (setting != null)
-          {
-            current.putSetting(setting);
-          }
-        }
-      }
-    }
-    catch (FileNotFoundException e)
-    {
-      Log.error("[SettingsFile] File not found: " + ini.getAbsolutePath() + e.getMessage());
+      Log.error("[SettingsFile] Error reading from: " + file.getAbsolutePath());
       if (view != null)
         view.onSettingsFileNotFound();
     }
-    catch (IOException e)
-    {
-      Log.error("[SettingsFile] Error reading from: " + ini.getAbsolutePath() + e.getMessage());
-      if (view != null)
-        view.onSettingsFileNotFound();
-    }
-    finally
-    {
-      if (reader != null)
-      {
-        try
-        {
-          reader.close();
-        }
-        catch (IOException e)
-        {
-          Log.error("[SettingsFile] Error closing: " + ini.getAbsolutePath() + e.getMessage());
-        }
-      }
-    }
-
-    return sections;
   }
 
-  public static HashMap<String, SettingSection> readFile(final String fileName,
-          SettingsActivityView view)
+  public static void readFile(final String fileName, IniFile ini, SettingsActivityView view)
   {
-    HashMap<String, SettingSection> sections = readFile(getSettingsFile(fileName), false, view);
+    readFile(getSettingsFile(fileName), ini, view);
 
     if (fileName.equals(SettingsFile.FILE_NAME_DOLPHIN))
     {
-      addGcPadSettingsIfTheyDontExist(sections);
+      addGcPadSettingsIfTheyDontExist(ini);
     }
-
-    return sections;
   }
 
   /**
-   * Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves
-   * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
-   * failed.
+   * Reads a given .ini file from disk and returns it.
+   * If unsuccessful, outputs an error telling why it failed.
    *
-   * @param gameId the id of the game to load it's settings.
+   * @param gameId the id of the game to load settings for.
+   * @param ini    The object to load into
    * @param view   The current view.
    */
-  public static HashMap<String, SettingSection> readCustomGameSettings(final String gameId,
+  public static void readCustomGameSettings(final String gameId, IniFile ini,
           SettingsActivityView view)
   {
-    return readFile(getCustomGameSettingsFile(gameId), true, view);
+    readFile(getCustomGameSettingsFile(gameId), ini, view);
   }
 
-  public static HashMap<String, SettingSection> readGenericGameSettings(final String gameId,
+  public static void readGenericGameSettings(final String gameId, IniFile ini,
           SettingsActivityView view)
   {
-    return readFile(getGenericGameSettingsFile(gameId), true, view);
+    readFile(getGenericGameSettingsFile(gameId), ini, view);
   }
 
-  public static HashMap<String, SettingSection> readGenericGameSettingsForAllRegions(
-          final String gameId, SettingsActivityView view)
+  public static void readGenericGameSettingsForAllRegions(final String gameId,
+          IniFile ini, SettingsActivityView view)
   {
-    return readFile(getGenericGameSettingsForAllRegions(gameId), true, view);
+    readFile(getGenericGameSettingsForAllRegions(gameId), ini, view);
   }
 
-  public static HashMap<String, SettingSection> readWiimoteProfile(final String gameId,
-          final String padId)
+  public static void readWiimoteProfile(final String gameId, IniFile ini, final int padId)
   {
     String profile = gameId + "_Wii" + padId;
-    return readFile(getWiiProfile(profile, padId), true, null);
+    readFile(getWiiProfile(profile), ini, null);
   }
 
   /**
-   * Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error
-   * telling why it failed.
+   * Saves a given .ini file on disk.
+   * If unsuccessful, outputs an error telling why it failed.
    *
    * @param fileName The target filename without a path or extension.
-   * @param sections The HashMap containing the Settings we want to serialize.
+   * @param ini      The IniFile we want to serialize.
    * @param view     The current view.
    */
-  public static void saveFile(final String fileName, TreeMap<String, SettingSection> sections,
-          SettingsActivityView view)
+  public static void saveFile(final String fileName, IniFile ini, SettingsActivityView view)
   {
-    File ini = getSettingsFile(fileName);
-
-    try (PrintWriter writer = new PrintWriter(ini, "UTF-8"))
+    if (!ini.save(getSettingsFile(fileName)))
     {
-
-      Set<String> keySet = sections.keySet();
-      Set<String> sortedKeySet = new TreeSet<>(keySet);
-
-      for (String key : sortedKeySet)
-      {
-        SettingSection section = sections.get(key);
-        writeSection(writer, section);
-      }
-    }
-    catch (FileNotFoundException e)
-    {
-      Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.getMessage());
+      Log.error("[SettingsFile] Error saving to: " + fileName + ".ini");
       if (view != null)
-        view.showToastMessage("Error saving " + fileName + ".ini: " + e.getMessage());
-    }
-    catch (UnsupportedEncodingException e)
-    {
-      Log.error("[SettingsFile] Bad encoding; please file a bug report: " + fileName + ".ini: " +
-              e.getMessage());
-      if (view != null)
-        view.showToastMessage("Error saving " + fileName + ".ini: " + e.getMessage());
+        view.showToastMessage("Error saving " + fileName + ".ini");
     }
   }
 
-  public static void saveCustomGameSettings(final String gameId,
-          final HashMap<String, SettingSection> sections)
+  public static void saveCustomGameSettings(final String gameId, IniFile ini)
   {
-    Set<String> sortedSections = new TreeSet<>(sections.keySet());
+    IniFile iniCopy = new IniFile(ini);
 
-    IniFile ini = new IniFile();
-    for (String sectionKey : sortedSections)
+    // Profile options(wii extension) are not saved, only used to properly display values
+    iniCopy.deleteSection(Settings.SECTION_PROFILE);
+
+    for (int i = 0; i < 3; i++)
     {
-      SettingSection section = sections.get(sectionKey);
-      HashMap<String, Setting> settings = section.getSettings();
-      Set<String> sortedKeySet = new TreeSet<>(settings.keySet());
-
-      // Profile options(wii extension) are not saved, only used to properly display values
-      if (sectionKey.contains(Settings.SECTION_PROFILE))
+      String key = SettingsFile.KEY_WIIMOTE_EXTENSION + i;
+      if (iniCopy.exists(Settings.SECTION_CONTROLS, key))
       {
-        continue;
-      }
-
-      for (String settingKey : sortedKeySet)
-      {
-        Setting setting = settings.get(settingKey);
         // Special case. Extension gets saved into a controller profile
-        if (settingKey.contains(SettingsFile.KEY_WIIMOTE_EXTENSION))
-        {
-          String padId =
-                  setting.getKey()
-                          .substring(setting.getKey().length() - 1, setting.getKey().length());
-          saveCustomWiimoteSetting(gameId, KEY_WIIMOTE_EXTENSION, setting.getValueAsString(),
-                  padId);
-        }
-        else
-        {
-          ini.setString(mapSectionNameFromIni(section.getName()), setting.getKey(),
-                  setting.getValueAsString());
-        }
+        String value = iniCopy.getString(Settings.SECTION_CONTROLS, key, "");
+        saveCustomWiimoteSetting(gameId, KEY_WIIMOTE_EXTENSION, value, i);
+        iniCopy.deleteKey(Settings.SECTION_CONTROLS, key);
       }
     }
-    ini.save(getCustomGameSettingsFile(gameId));
+
+    iniCopy.save(getCustomGameSettingsFile(gameId));
   }
 
   /**
@@ -509,13 +397,13 @@ public final class SettingsFile
    * @param padId
    */
   private static void saveCustomWiimoteSetting(final String gameId, final String key,
-          final String value, final String padId)
+          final String value, final int padId)
   {
     String profile = gameId + "_Wii" + padId;
     String wiiConfigPath =
             DirectoryInitialization.getUserDirectory() + "/Config/Profiles/Wiimote/" +
                     profile + ".ini";
-    File wiiProfile = getWiiProfile(profile, padId);
+    File wiiProfile = getWiiProfile(profile);
     // If it doesn't exist, create it
     boolean wiiProfileExists = wiiProfile.exists();
     if (!wiiProfileExists)
@@ -531,7 +419,7 @@ public final class SettingsFile
     if (!wiiProfileExists)
     {
       wiiProfileIni.setString(Settings.SECTION_PROFILE, "Device",
-              "Android/" + (Integer.parseInt(padId) + 4) + "/Touchscreen");
+              "Android/" + (padId + 4) + "/Touchscreen");
     }
 
     wiiProfileIni.setString(Settings.SECTION_PROFILE, key, value);
@@ -540,12 +428,12 @@ public final class SettingsFile
     // Enable the profile
     File gameSettingsFile = SettingsFile.getCustomGameSettingsFile(gameId);
     IniFile gameSettingsIni = new IniFile(gameSettingsFile);
-    gameSettingsIni.setString(Settings.SECTION_CONTROLS,
-            KEY_WIIMOTE_PROFILE + (Integer.parseInt(padId) + 1), profile);
+    gameSettingsIni.setString(Settings.SECTION_CONTROLS, KEY_WIIMOTE_PROFILE + (padId + 1),
+            profile);
     gameSettingsIni.save(gameSettingsFile);
   }
 
-  private static String mapSectionNameFromIni(String generalSectionName)
+  public static String mapSectionNameFromIni(String generalSectionName)
   {
     if (sectionsMap.getForward(generalSectionName) != null)
     {
@@ -555,7 +443,7 @@ public final class SettingsFile
     return generalSectionName;
   }
 
-  private static String mapSectionNameToIni(String generalSectionName)
+  public static String mapSectionNameToIni(String generalSectionName)
   {
     if (sectionsMap.getBackward(generalSectionName) != null)
     {
@@ -594,7 +482,7 @@ public final class SettingsFile
             DirectoryInitialization.getUserDirectory() + "/GameSettings/" + gameId + ".ini");
   }
 
-  private static File getWiiProfile(String profile, String padId)
+  private static File getWiiProfile(String profile)
   {
     String wiiConfigPath =
             DirectoryInitialization.getUserDirectory() + "/Config/Profiles/Wiimote/" +
@@ -603,136 +491,29 @@ public final class SettingsFile
     return new File(wiiConfigPath);
   }
 
-  private static SettingSection sectionFromLine(String line, boolean isCustomGame)
+  private static void addGcPadSettingsIfTheyDontExist(IniFile ini)
   {
-    String sectionName = line.substring(1, line.length() - 1);
-    if (isCustomGame)
-    {
-      sectionName = mapSectionNameToIni(sectionName);
-    }
-    return new SettingSection(sectionName);
-  }
-
-  private static void addGcPadSettingsIfTheyDontExist(HashMap<String, SettingSection> sections)
-  {
-    SettingSection coreSection = sections.get(Settings.SECTION_INI_CORE);
+    IniFile.Section coreSection = ini.getOrCreateSection(Settings.SECTION_INI_CORE);
 
     for (int i = 0; i < 4; i++)
     {
       String key = SettingsFile.KEY_GCPAD_TYPE + i;
-      if (coreSection.getSetting(key) == null)
+      if (!coreSection.exists(key))
       {
         // Set GameCube controller 1 to enabled, all others disabled
-        Setting gcPadSetting = new IntSetting(key, Settings.SECTION_INI_CORE, i == 0 ? 6 : 0);
-        coreSection.putSetting(gcPadSetting);
+        coreSection.setInt(key, i == 0 ? 6 : 0);
       }
     }
-
-    sections.put(Settings.SECTION_INI_CORE, coreSection);
   }
 
   public static void firstAnalyticsAdd(boolean enabled)
   {
-    HashMap<String, SettingSection> dolphinSections =
-            readFile(SettingsFile.FILE_NAME_DOLPHIN, null);
-    SettingSection analyticsSection = dolphinSections.get(Settings.SECTION_ANALYTICS);
+    IniFile dolphinIni = new IniFile();
+    readFile(SettingsFile.FILE_NAME_DOLPHIN, dolphinIni, null);
 
-    Setting analyticsEnabled = new StringSetting(KEY_ANALYTICS_ENABLED, Settings.SECTION_ANALYTICS,
-            enabled ? "True" : "False");
-    Setting analyticsFirstAsk =
-            new StringSetting(KEY_ANALYTICS_PERMISSION_ASKED, Settings.SECTION_ANALYTICS, "True");
+    dolphinIni.setBoolean(Settings.SECTION_ANALYTICS, KEY_ANALYTICS_ENABLED, enabled);
+    dolphinIni.setBoolean(Settings.SECTION_ANALYTICS, KEY_ANALYTICS_PERMISSION_ASKED, true);
 
-    analyticsSection.putSetting(analyticsFirstAsk);
-    analyticsSection.putSetting(analyticsEnabled);
-
-    dolphinSections.put(Settings.SECTION_ANALYTICS, analyticsSection);
-
-    TreeMap<String, SettingSection> saveSection = new TreeMap<>(dolphinSections);
-    saveFile(SettingsFile.FILE_NAME_DOLPHIN, saveSection, null);
-  }
-
-  /**
-   * 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("=");
-
-    if (splitLine.length != 2)
-    {
-      Log.warning("Skipping invalid config line \"" + line + "\"");
-      return null;
-    }
-
-    String key = splitLine[0].trim();
-    String value = splitLine[1].trim();
-
-    try
-    {
-      int valueAsInt = Integer.parseInt(value);
-
-      return new IntSetting(key, current.getName(), valueAsInt);
-    }
-    catch (NumberFormatException ignored)
-    {
-    }
-
-    try
-    {
-      float valueAsFloat = Float.parseFloat(value);
-
-      return new FloatSetting(key, current.getName(), valueAsFloat);
-    }
-    catch (NumberFormatException ignored)
-    {
-    }
-
-    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();
-    Set<String> sortedKeySet = new TreeSet<>(keySet);
-
-    for (String key : sortedKeySet)
-    {
-      Setting setting = settings.get(key);
-      String valueAsString = setting.getValueAsString();
-      if (!TextUtils.isEmpty(valueAsString))
-      {
-        writer.println(setting.getKey() + " = " + valueAsString);
-      }
-    }
-  }
-
-  private static String sectionAsString(SettingSection section)
-  {
-    return "[" + section.getName() + "]";
+    saveFile(SettingsFile.FILE_NAME_DOLPHIN, dolphinIni, null);
   }
 }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java
index bef1d7f7a8..06d1dd71d6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java
@@ -15,7 +15,6 @@ import android.widget.TextView;
 import org.dolphinemu.dolphinemu.NativeLibrary;
 import org.dolphinemu.dolphinemu.R;
 import org.dolphinemu.dolphinemu.activities.EmulationActivity;
-import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 
@@ -72,12 +71,11 @@ public final class MenuFragment extends Fragment implements View.OnClickListener
       showUnpauseEmulationButton();
     }
 
-    BooleanSetting enableSaveStates =
-            (BooleanSetting) ((EmulationActivity) getActivity()).getSettings()
-                    .getSection(Settings.SECTION_INI_CORE)
-                    .getSetting(SettingsFile.KEY_ENABLE_SAVE_STATES);
+    boolean enableSaveStates = ((EmulationActivity) getActivity()).getSettings()
+            .getSection(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE)
+            .getBoolean(SettingsFile.KEY_ENABLE_SAVE_STATES, false);
 
-    if (enableSaveStates != null && enableSaveStates.getValue())
+    if (enableSaveStates)
     {
       options.findViewById(R.id.menu_quicksave).setVisibility(View.VISIBLE);
       options.findViewById(R.id.menu_quickload).setVisibility(View.VISIBLE);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java
index ecbe7b3122..c8787a3ec8 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/IniFile.java
@@ -15,6 +15,26 @@ public class IniFile
     {
       mPointer = pointer;
     }
+
+    public native boolean exists(String key);
+
+    public native boolean delete(String key);
+
+    public native String getString(String key, String defaultValue);
+
+    public native boolean getBoolean(String key, boolean defaultValue);
+
+    public native int getInt(String key, int defaultValue);
+
+    public native float getFloat(String key, float defaultValue);
+
+    public native void setString(String key, String newValue);
+
+    public native void setBoolean(String key, boolean newValue);
+
+    public native void setInt(String key, int newValue);
+
+    public native void setFloat(String key, float newFloat);
   }
 
   private long mPointer;  // Do not rename or move without editing the native code
@@ -24,6 +44,11 @@ public class IniFile
     mPointer = newIniFile();
   }
 
+  public IniFile(IniFile other)
+  {
+    mPointer = copyIniFile(other);
+  }
+
   public IniFile(String path)
   {
     this();
@@ -50,20 +75,36 @@ public class IniFile
     return save(file.getPath());
   }
 
+  public native Section getOrCreateSection(String sectionName);
+
+  public native boolean exists(String sectionName);
+
+  public native boolean exists(String sectionName, String key);
+
+  public native boolean deleteSection(String sectionName);
+
+  public native boolean deleteKey(String sectionName, String key);
+
   public native String getString(String sectionName, String key, String defaultValue);
 
   public native boolean getBoolean(String sectionName, String key, boolean defaultValue);
 
   public native int getInt(String sectionName, String key, int defaultValue);
 
+  public native float getFloat(String sectionName, String key, float defaultValue);
+
   public native void setString(String sectionName, String key, String newValue);
 
   public native void setBoolean(String sectionName, String key, boolean newValue);
 
   public native void setInt(String sectionName, String key, int newValue);
 
+  public native void setFloat(String sectionName, String key, float newValue);
+
   @Override
   public native void finalize();
 
   private native long newIniFile();
+
+  private native long copyIniFile(IniFile other);
 }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Rumble.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Rumble.java
index aa37a318ef..a0930d9f06 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Rumble.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Rumble.java
@@ -10,7 +10,6 @@ import android.view.InputDevice;
 
 import org.dolphinemu.dolphinemu.activities.EmulationActivity;
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
-import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
 import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 
 public class Rumble
@@ -29,15 +28,16 @@ public class Rumble
 
     for (int i = 0; i < 8; i++)
     {
-      StringSetting deviceName =
-              (StringSetting) activity.getSettings().getSection(Settings.SECTION_BINDINGS)
-                      .getSetting(SettingsFile.KEY_EMU_RUMBLE + i);
-      if (deviceName != null && !deviceName.getValue().isEmpty())
+      String deviceName = activity.getSettings()
+              .getSection(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_BINDINGS)
+              .getString(SettingsFile.KEY_EMU_RUMBLE + i, "");
+
+      if (!deviceName.isEmpty())
       {
         for (int id : InputDevice.getDeviceIds())
         {
           InputDevice device = InputDevice.getDevice(id);
-          if (deviceName.getValue().equals(device.getDescriptor()))
+          if (deviceName.equals(device.getDescriptor()))
           {
             Vibrator vib = device.getVibrator();
             if (vib != null && vib.hasVibrator())
diff --git a/Source/Android/jni/IniFile.cpp b/Source/Android/jni/IniFile.cpp
index 0237fec4dc..d275dcff00 100644
--- a/Source/Android/jni/IniFile.cpp
+++ b/Source/Android/jni/IniFile.cpp
@@ -28,6 +28,20 @@ static jobject SectionToJava(JNIEnv* env, jobject ini_file, IniFile::Section* se
                         ini_file, reinterpret_cast<jlong>(section));
 }
 
+template <typename T>
+static T GetInSection(JNIEnv* env, jobject obj, jstring key, T default_value)
+{
+  T result;
+  GetSectionPointer(env, obj)->Get(GetJString(env, key), &result, default_value);
+  return result;
+}
+
+template <typename T>
+static void SetInSection(JNIEnv* env, jobject obj, jstring key, T new_value)
+{
+  GetSectionPointer(env, obj)->Set(GetJString(env, key), new_value);
+}
+
 template <typename T>
 static T Get(JNIEnv* env, jobject obj, jstring section_name, jstring key, T default_value)
 {
@@ -50,6 +64,66 @@ static void Set(JNIEnv* env, jobject obj, jstring section_name, jstring key, T n
 extern "C" {
 #endif
 
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_exists(
+    JNIEnv* env, jobject obj, jstring key)
+{
+  return static_cast<jboolean>(GetSectionPointer(env, obj)->Exists(GetJString(env, key)));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_delete(
+    JNIEnv* env, jobject obj, jstring key)
+{
+  return static_cast<jboolean>(GetSectionPointer(env, obj)->Delete(GetJString(env, key)));
+}
+
+JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_getString(
+    JNIEnv* env, jobject obj, jstring key, jstring default_value)
+{
+  return ToJString(env, GetInSection(env, obj, key, GetJString(env, default_value)));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_getBoolean(
+    JNIEnv* env, jobject obj, jstring key, jboolean default_value)
+{
+  return static_cast<jboolean>(GetInSection(env, obj, key, static_cast<bool>(default_value)));
+}
+
+JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_getInt(
+    JNIEnv* env, jobject obj, jstring key, jint default_value)
+{
+  return GetInSection(env, obj, key, default_value);
+}
+
+JNIEXPORT jfloat JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_getFloat(
+    JNIEnv* env, jobject obj, jstring key, jfloat default_value)
+{
+  return GetInSection(env, obj, key, default_value);
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_setString(
+    JNIEnv* env, jobject obj, jstring key, jstring new_value)
+{
+  SetInSection(env, obj, key, GetJString(env, new_value));
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_setBoolean(
+    JNIEnv* env, jobject obj, jstring key, jboolean new_value)
+{
+  SetInSection(env, obj, key, static_cast<bool>(new_value));
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_setInt(
+    JNIEnv* env, jobject obj, jstring key, jint new_value)
+{
+  SetInSection(env, obj, key, new_value);
+}
+
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_00024Section_setFloat(
+    JNIEnv* env, jobject obj, jstring key, jfloat new_value)
+{
+  SetInSection(env, obj, key, new_value);
+}
+
 JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_load(
     JNIEnv* env, jobject obj, jstring path, jboolean keep_current_data)
 {
@@ -64,6 +138,41 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_save(JNI
   return static_cast<jboolean>(GetIniFilePointer(env, obj)->Save(GetJString(env, path)));
 }
 
+JNIEXPORT jobject JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getOrCreateSection(
+    JNIEnv* env, jobject obj, jstring section_name)
+{
+  return SectionToJava(
+      env, obj, GetIniFilePointer(env, obj)->GetOrCreateSection(GetJString(env, section_name)));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_exists__Ljava_lang_String_2(
+    JNIEnv* env, jobject obj, jstring section_name)
+{
+  return static_cast<jboolean>(GetIniFilePointer(env, obj)->Exists(GetJString(env, section_name)));
+}
+
+JNIEXPORT jboolean JNICALL
+Java_org_dolphinemu_dolphinemu_utils_IniFile_exists__Ljava_lang_String_2Ljava_lang_String_2(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key)
+{
+  return static_cast<jboolean>(
+      GetIniFilePointer(env, obj)->Exists(GetJString(env, section_name), GetJString(env, key)));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_deleteSection(
+    JNIEnv* env, jobject obj, jstring section_name)
+{
+  return static_cast<jboolean>(
+      GetIniFilePointer(env, obj)->DeleteSection(GetJString(env, section_name)));
+}
+
+JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_deleteKey(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key)
+{
+  return static_cast<jboolean>(
+      GetIniFilePointer(env, obj)->DeleteKey(GetJString(env, section_name), GetJString(env, key)));
+}
+
 JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getString(
     JNIEnv* env, jobject obj, jstring section_name, jstring key, jstring default_value)
 {
@@ -84,6 +193,12 @@ JNIEXPORT jint JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getInt(JNIEn
   return Get(env, obj, section_name, key, default_value);
 }
 
+JNIEXPORT jfloat JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_getFloat(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key, jfloat default_value)
+{
+  return Get(env, obj, section_name, key, default_value);
+}
+
 JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_setString(
     JNIEnv* env, jobject obj, jstring section_name, jstring key, jstring new_value)
 {
@@ -104,6 +219,12 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_setInt(JNIEn
   Set(env, obj, section_name, key, new_value);
 }
 
+JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_setFloat(
+    JNIEnv* env, jobject obj, jstring section_name, jstring key, jfloat new_value)
+{
+  Set(env, obj, section_name, key, new_value);
+}
+
 JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_finalize(JNIEnv* env,
                                                                              jobject obj)
 {
@@ -116,6 +237,13 @@ JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_newIniFile(
   return reinterpret_cast<jlong>(new IniFile);
 }
 
+JNIEXPORT jlong JNICALL Java_org_dolphinemu_dolphinemu_utils_IniFile_copyIniFile(JNIEnv* env,
+                                                                                 jobject obj,
+                                                                                 jobject other)
+{
+  return reinterpret_cast<jlong>(new IniFile(*GetIniFilePointer(env, other)));
+}
+
 #ifdef __cplusplus
 }
 #endif

From ee9444a8f975516c5b5481bbd2b1d402a570dd7f Mon Sep 17 00:00:00 2001
From: JosJuice <josjuice@gmail.com>
Date: Tue, 7 Jul 2020 15:18:37 +0200
Subject: [PATCH 3/3] Android: Create separate InvertedCheckBoxSetting and
 PercentSliderSetting classes

This way we don't have to hardcode any keys inside the classes.
---
 .../settings/model/view/CheckBoxSetting.java  | 21 +++-------------
 .../model/view/FloatSliderSetting.java        | 19 +++-----------
 .../model/view/InvertedCheckBoxSetting.java   | 25 +++++++++++++++++++
 .../model/view/PercentSliderSetting.java      | 25 +++++++++++++++++++
 .../ui/SettingsFragmentPresenter.java         | 10 +++++---
 5 files changed, 63 insertions(+), 37 deletions(-)
 create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InvertedCheckBoxSetting.java
 create mode 100644 Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/PercentSliderSetting.java

diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java
index a322f863a4..8e03ac038c 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/CheckBoxSetting.java
@@ -1,11 +1,10 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
-import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 
-public final class CheckBoxSetting extends SettingsItem
+public class CheckBoxSetting extends SettingsItem
 {
-  private boolean mDefaultValue;
+  protected boolean mDefaultValue;
 
   public CheckBoxSetting(String file, String section, String key, int titleId, int descriptionId,
           boolean defaultValue)
@@ -16,24 +15,12 @@ public final class CheckBoxSetting extends SettingsItem
 
   public boolean isChecked(Settings settings)
   {
-    return invertIfNeeded(settings.getSection(getFile(), getSection())
-            .getBoolean(getKey(), invertIfNeeded(mDefaultValue)));
+    return settings.getSection(getFile(), getSection()).getBoolean(getKey(), mDefaultValue);
   }
 
   public void setChecked(Settings settings, boolean checked)
   {
-    settings.getSection(getFile(), getSection()).setBoolean(getKey(), invertIfNeeded(checked));
-  }
-
-  private boolean invertIfNeeded(boolean x)
-  {
-    return isInverted() ? !x : x;
-  }
-
-  private boolean isInverted()
-  {
-    return getKey().equals(SettingsFile.KEY_SKIP_EFB) ||
-            getKey().equals(SettingsFile.KEY_IGNORE_FORMAT);
+    settings.getSection(getFile(), getSection()).setBoolean(getKey(), checked);
   }
 
   @Override
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java
index 39ce129822..06c27989de 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/FloatSliderSetting.java
@@ -1,39 +1,26 @@
 package org.dolphinemu.dolphinemu.features.settings.model.view;
 
 import org.dolphinemu.dolphinemu.features.settings.model.Settings;
-import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
 
-public final class FloatSliderSetting extends SliderSetting
+public class FloatSliderSetting extends SliderSetting
 {
-  private float mDefaultValue;
+  protected float mDefaultValue;
 
   public FloatSliderSetting(String file, String section, String key, int titleId, int descriptionId,
           int max, String units, float defaultValue)
   {
     super(file, section, key, titleId, descriptionId, max, units);
     mDefaultValue = defaultValue;
-
-    if (isPercentSetting())
-      mDefaultValue /= 100;
   }
 
   public int getSelectedValue(Settings settings)
   {
     float value = settings.getSection(getFile(), getSection()).getFloat(getKey(), mDefaultValue);
-    return Math.round(isPercentSetting() ? value * 100 : value);
+    return Math.round(value);
   }
 
   public void setSelectedValue(Settings settings, float selection)
   {
-    if (isPercentSetting())
-      selection /= 100;
-
     settings.getSection(getFile(), getSection()).setFloat(getKey(), selection);
   }
-
-  private boolean isPercentSetting()
-  {
-    return getKey().equals(SettingsFile.KEY_OVERCLOCK_PERCENT)
-            || getKey().equals(SettingsFile.KEY_SPEED_LIMIT);
-  }
 }
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InvertedCheckBoxSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InvertedCheckBoxSetting.java
new file mode 100644
index 0000000000..ff807d599b
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/InvertedCheckBoxSetting.java
@@ -0,0 +1,25 @@
+package org.dolphinemu.dolphinemu.features.settings.model.view;
+
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
+import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
+
+public final class InvertedCheckBoxSetting extends CheckBoxSetting
+{
+  public InvertedCheckBoxSetting(String file, String section, String key, int titleId,
+          int descriptionId, boolean defaultValue)
+  {
+    super(file, section, key, titleId, descriptionId, !defaultValue);
+  }
+
+  @Override
+  public boolean isChecked(Settings settings)
+  {
+    return !settings.getSection(getFile(), getSection()).getBoolean(getKey(), mDefaultValue);
+  }
+
+  @Override
+  public void setChecked(Settings settings, boolean checked)
+  {
+    settings.getSection(getFile(), getSection()).setBoolean(getKey(), !checked);
+  }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/PercentSliderSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/PercentSliderSetting.java
new file mode 100644
index 0000000000..dda5a6a774
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/view/PercentSliderSetting.java
@@ -0,0 +1,25 @@
+package org.dolphinemu.dolphinemu.features.settings.model.view;
+
+import org.dolphinemu.dolphinemu.features.settings.model.Settings;
+
+public final class PercentSliderSetting extends FloatSliderSetting
+{
+  public PercentSliderSetting(String file, String section, String key, int titleId,
+          int descriptionId, int max, String units, float defaultValue)
+  {
+    super(file, section, key, titleId, descriptionId, max, units, defaultValue / 100);
+  }
+
+  @Override
+  public int getSelectedValue(Settings settings)
+  {
+    float value = settings.getSection(getFile(), getSection()).getFloat(getKey(), mDefaultValue);
+    return Math.round(value * 100);
+  }
+
+  @Override
+  public void setSelectedValue(Settings settings, float selection)
+  {
+    settings.getSection(getFile(), getSection()).setFloat(getKey(), selection / 100);
+  }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
index 6ac485f58c..b4bf525af4 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java
@@ -13,6 +13,8 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.FloatSliderSetting
 import org.dolphinemu.dolphinemu.features.settings.model.view.HeaderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.IntSliderSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.view.InvertedCheckBoxSetting;
+import org.dolphinemu.dolphinemu.features.settings.model.view.PercentSliderSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.RumbleBindingSetting;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
 import org.dolphinemu.dolphinemu.features.settings.model.view.SingleChoiceSetting;
@@ -226,7 +228,7 @@ public final class SettingsFragmentPresenter
             false));
     sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
             SettingsFile.KEY_AUTO_DISC_CHANGE, R.string.auto_disc_change, 0, false));
-    sl.add(new FloatSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+    sl.add(new PercentSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
             SettingsFile.KEY_SPEED_LIMIT, R.string.speed_limit, 0, 200, "%", 100));
     sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_ANALYTICS,
             SettingsFile.KEY_ANALYTICS_ENABLED, R.string.analytics, 0, false));
@@ -356,7 +358,7 @@ public final class SettingsFragmentPresenter
     sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
             SettingsFile.KEY_OVERCLOCK_ENABLE, R.string.overclock_enable,
             R.string.overclock_enable_description, false));
-    sl.add(new FloatSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
+    sl.add(new PercentSliderSetting(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE,
             SettingsFile.KEY_OVERCLOCK_PERCENT, R.string.overclock_title,
             R.string.overclock_title_description, 400, "%", 100));
   }
@@ -544,10 +546,10 @@ public final class SettingsFragmentPresenter
   private void addHackSettings(ArrayList<SettingsItem> sl)
   {
     sl.add(new HeaderSetting(null, R.string.embedded_frame_buffer, 0));
-    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+    sl.add(new InvertedCheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
             SettingsFile.KEY_SKIP_EFB, R.string.skip_efb_access,
             R.string.skip_efb_access_description, false));
-    sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
+    sl.add(new InvertedCheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,
             SettingsFile.KEY_IGNORE_FORMAT, R.string.ignore_format_changes,
             R.string.ignore_format_changes_description, true));
     sl.add(new CheckBoxSetting(SettingsFile.FILE_NAME_GFX, Settings.SECTION_GFX_HACKS,