public static void Load(string filepath)
    {
        INIParser iniparse = new INIParser();

        iniparse.Open(filepath);

        // Check for valid fps values
        targetFramerate         = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Framerate", 120);
        hyperspeed              = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Hyperspeed", 5.0f);
        highwayLength           = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Highway Length", 0);
        audioCalibrationMS      = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Audio calibration", 0);
        clapCalibrationMS       = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Clap calibration", 0);
        clapProperties          = (ClapToggle)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Clap", (int)ClapToggle.ALL);
        extendedSustainsEnabled = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Extended sustains", false);
        clapSetting             = ClapToggle.NONE;
        sustainGapEnabled       = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap", false);
        sustainGapStep          = new Step((int)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap Step", (int)16));
        notePlacementMode       = (NotePlacementMode)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Note Placement Mode", (int)NotePlacementMode.Default);
        gameplayStartDelayTime  = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Gameplay Start Delay", 3.0f);
        resetAfterPlay          = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Reset After Play", false);
        resetAfterGameplay      = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Reset After Gameplay", false);
        customBgSwapTime        = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Custom Background Swap Time", 30);
        gameplayStartDelayTime  = Mathf.Clamp(gameplayStartDelayTime, 0, 3.0f);
        gameplayStartDelayTime  = (float)(System.Math.Round(gameplayStartDelayTime * 2.0f, System.MidpointRounding.AwayFromZero) / 2.0f);         // Check that the gameplay start delay time is a multiple of 0.5 and is

        // Audio levels
        vol_master = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Master", 0.5f);
        vol_song   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Music Stream", 1.0f);
        vol_guitar = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Guitar Stream", 1.0f);
        vol_bass   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Bass Stream", 1.0f);
        vol_rhythm = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Rhythm Stream", 1.0f);
        vol_drum   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Drum Stream", 1.0f);
        audio_pan  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Audio Pan", 0.0f);
        sfxVolume  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "SFX", 1.0f);

        iniparse.Close();
    }
    public static void Load(string configFilepath, string controllerBindingsFilepath)
    {
        INIParser iniparse = new INIParser();

        try
        {
            Debug.Log("Loading game settings");

            iniparse.Open(configFilepath);

            // Check for valid fps values
            targetFramerate         = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Framerate", 120);
            hyperspeed              = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Hyperspeed", 5.0f);
            highwayLength           = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Highway Length", 0);
            audioCalibrationMS      = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Audio calibration", 0);
            clapCalibrationMS       = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Clap calibration", 0);
            clapProperties          = (ClapToggle)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Clap", c_defaultClapVal);
            extendedSustainsEnabled = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Extended sustains", false);
            clapEnabled             = false;
            sustainGapEnabled       = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap", false);
            sustainGapStep          = new Step((int)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap Step", (int)16));
            notePlacementMode       = (NotePlacementMode)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Note Placement Mode", (int)NotePlacementMode.Default);
            gameplayStartDelayTime  = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Gameplay Start Delay", 3.0f);
            resetAfterPlay          = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Reset After Play", false);
            resetAfterGameplay      = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Reset After Gameplay", false);
            customBgSwapTime        = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Custom Background Swap Time", 30);
            gameplayStartDelayTime  = Mathf.Clamp(gameplayStartDelayTime, 0, 3.0f);
            gameplayStartDelayTime  = (float)(System.Math.Round(gameplayStartDelayTime * 2.0f, System.MidpointRounding.AwayFromZero) / 2.0f); // Check that the gameplay start delay time is a multiple of 0.5 and is

            // Audio levels
            vol_master = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Master", 0.5f);
            vol_song   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Music Stream", 1.0f);
            vol_guitar = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Guitar Stream", 1.0f);
            vol_bass   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Bass Stream", 1.0f);
            vol_rhythm = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Rhythm Stream", 1.0f);
            vol_drum   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Drum Stream", 1.0f);
            audio_pan  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Audio Pan", 0.0f);
            sfxVolume  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "SFX", 1.0f);

            // Need to fix old config values
            if ((int)clapProperties > (((int)ClapToggle.SECTION << 1) - 1))
            {
                clapProperties = (ClapToggle)c_defaultClapVal;
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError("Error encountered when trying to load game settings. " + e.Message);
        }
        finally
        {
            iniparse.Close();
        }

        try
        {
            // Populate with all default controls first
            controls.LoadFromSaveData(InputManager.Instance.defaultControls);

            if (File.Exists(controllerBindingsFilepath))
            {
                // Override with custom controls if they exist.
                Debug.Log("Loading input settings");
                string controlsJson = File.ReadAllText(controllerBindingsFilepath);
                controls.LoadFromSaveData(JsonUtility.FromJson <MSChartEditorInput.MSChartEditorActionContainer>(controlsJson));
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError("Unable to load saved controls. " + e.Message);
        }
    }
    public void Load(string configFilepath, string controllerBindingsFilepath)
    {
        INIParser iniparse = new INIParser();

        try
        {
            Debug.Log("Loading game settings");

            iniparse.Open(configFilepath);

            // Check for valid fps values
            targetFramerate                = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Framerate", 120);
            hyperspeed                     = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Hyperspeed", 5.0f);
            highwayLength                  = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Highway Length", 0);
            audioCalibrationMS             = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Audio calibration", 0);
            clapCalibrationMS              = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Clap calibration", 0);
            clapProperties                 = (ClapToggle)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Clap", c_defaultClapVal);
            extendedSustainsEnabled        = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Extended sustains", false);
            clapEnabled                    = false;
            sustainGapEnabled              = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap", false);
            sustainGapIsTimeBased          = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap Is Time Based", false);
            sustainGapStep                 = new Step((int)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap Step", (int)16));
            sustainGapTimeMs               = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Sustain Gap Time", (int)0);
            notePlacementMode              = (NotePlacementMode)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Note Placement Mode", (int)NotePlacementMode.Default);
            gameplayStartDelayTime         = (float)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Gameplay Start Delay", 3.0f);
            resetAfterPlay                 = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Reset After Play", false);
            resetAfterGameplay             = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Reset After Gameplay", false);
            slowdownPitchCorrectionEnabled = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Slowdown Pitch Correction Enabled", false);
            customBgSwapTime               = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Custom Background Swap Time", 30);
            drumsLaneCount                 = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Drums Lane Count", 5);
            drumsModeOptions               = (DrumModeOptions)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Drums Mode", (int)DrumModeOptions.Standard);
            if (!System.Enum.IsDefined(typeof(DrumModeOptions), drumsModeOptions))
            {
                drumsModeOptions = DrumModeOptions.Standard;
            }
            songValidatorModes           = (SongValidate.ValidationOptions)iniparse.ReadValue(SECTION_NAME_SETTINGS, "Song Validator Modes", (int)(~SongValidate.ValidationOptions.None));
            autoValidateSongOnSave       = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Auto Validate Song On Save", true);
            automaticallyCheckForUpdates = iniparse.ReadValue(SECTION_NAME_SETTINGS, "Auto Check For Updates", true);

            gameplayStartDelayTime = Mathf.Clamp(gameplayStartDelayTime, 0, 3.0f);
            gameplayStartDelayTime = (float)(System.Math.Round(gameplayStartDelayTime * 2.0f, System.MidpointRounding.AwayFromZero) / 2.0f); // Check that the gameplay start delay time is a multiple of 0.5 and is

            // Audio levels
            vol_master = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Master", 0.5f);
            vol_song   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Music Stream", 1.0f);
            vol_guitar = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Guitar Stream", 1.0f);
            vol_bass   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Bass Stream", 1.0f);
            vol_rhythm = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Rhythm Stream", 1.0f);
            vol_keys   = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Keys Stream", 1.0f);
            vol_vocals = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Vocals Stream", 1.0f);
            vol_drums  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Drum Stream", 1.0f);
            vol_drums2 = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Drum 2 Stream", 1.0f);
            vol_drums3 = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Drum 3 Stream", 1.0f);
            vol_drums4 = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Drum 4 Stream", 1.0f);
            vol_crowd  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Crowd Stream", 1.0f);
            audio_pan  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "Audio Pan", 0.0f);
            sfxVolume  = (float)iniparse.ReadValue(SECTION_NAME_AUDIO, "SFX", 1.0f);

            // Need to fix old config values
            if ((int)clapProperties > (((int)ClapToggle.SECTION << 1) - 1))
            {
                clapProperties = (ClapToggle)c_defaultClapVal;
            }

            // Graphics Settings
            QualitySettings.antiAliasing = iniparse.ReadValue(SECTION_NAME_GRAPHICS, "AntiAliasingLevel", QualitySettings.antiAliasing);
        }
        catch (System.Exception e)
        {
            Debug.LogError("Error encountered when trying to load game settings. " + e.Message);
        }
        finally
        {
            iniparse.Close();
        }

        try
        {
            // Populate with all default controls first
            controls.LoadFromSaveData(InputManager.Instance.defaultControls);

            if (File.Exists(controllerBindingsFilepath))
            {
                // Override with custom controls if they exist.
                Debug.Log("Loading input settings");
                string controlsJson = File.ReadAllText(controllerBindingsFilepath);
                controls.LoadFromSaveData(JsonUtility.FromJson <MSChartEditorInput.MSChartEditorActionContainer>(controlsJson));
            }
        }
        catch (System.Exception e)
        {
            Debug.LogError("Unable to load saved controls. " + e.Message);
        }
    }