diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index 585eac4e..9bb459f9 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -2768,7 +2768,7 @@ void CControllerConfigManager::ResetSettingOrder(e_ControllerAction action)
 			for (int32 k = 0; k < MAX_CONTROLLERTYPES; k++)
 			{
 				int32 setorder = m_aSettings[action][k].m_ContSetOrder;
-				if (setorder > i && setorder != KEYBOARD)
+				if (setorder > i && setorder != 0)
 				{
 					if (init)
 					{
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index 086a9887..12e4b16a 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -563,13 +563,21 @@ CMenuManager::Initialise(void)
 	DMAudio.Service();
 	DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
 	DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+#ifdef FIX_BUGS
+	static bool firstTime = true;
+	if (firstTime) {
+		DMAudio.SetRadioInCar(m_PrefsRadioStation);
+		firstTime = false;
+	} else
+#endif
 	m_PrefsRadioStation = DMAudio.GetRadioInCar();
+
 	DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
 	if (DMAudio.IsMP3RadioChannelAvailable()) {
 		if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK)
-			m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
+			m_PrefsRadioStation = CGeneral::GetRandomNumber() % (USERTRACK + 1);
 	} else if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > WAVE)
-		m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
+		m_PrefsRadioStation = CGeneral::GetRandomNumber() % (WAVE + 1);
 
 	CFileMgr::SetDir("");
 	//CFileMgr::SetDir("");
@@ -653,7 +661,11 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
 		m_bWaitingForNewKeyBind = false;
 		m_KeyPressedCode = -1;
 		m_bStartWaitingForKeyBind = false;
+#ifdef LOAD_INI_SETTINGS
+		SaveINIControllerSettings();
+#else
 		SaveSettings();
+#endif
 	}
 }
 
@@ -3032,6 +3044,11 @@ CMenuManager::LoadSettings()
 	CFileMgr::CloseFile(fileHandle);
 	CFileMgr::SetDir("");
 
+#ifdef LOAD_INI_SETTINGS
+	LoadINISettings();
+	LoadINIControllerSettings(); // Calling that after LoadINISettings is important because of gSelectedJoystickName loading
+#endif
+
 #ifdef FIX_BUGS
 	TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
 #endif
@@ -3077,15 +3094,12 @@ CMenuManager::LoadSettings()
 		strcpy(m_PrefsSkinFile, DEFAULT_SKIN_NAME);
 		strcpy(m_aSkinName, DEFAULT_SKIN_NAME);
 	}
-	
-#ifdef LOAD_INI_SETTINGS
-	LoadINISettings(); // needs frontend options to be loaded
-#endif
 }
 
 void
 CMenuManager::SaveSettings()
 {
+#ifndef LOAD_INI_SETTINGS
 	static char RubbishString[48] = "stuffmorestuffevenmorestuff                 etc";
 	static int SomeVersion = 3;
 
@@ -3144,7 +3158,14 @@ CMenuManager::SaveSettings()
 	CFileMgr::CloseFile(fileHandle);
 	CFileMgr::SetDir("");
 	
-#ifdef LOAD_INI_SETTINGS
+#else
+	m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex;
+	static bool firstTime = true;
+	// In other conditions we already call SaveINIControllerSettings explicitly.
+	if (firstTime) {
+		SaveINIControllerSettings();
+		firstTime = false;
+	}
 	SaveINISettings();
 #endif
 }
@@ -4424,19 +4445,19 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
 			MouseButtonJustClicked = false;
 
 			if (CPad::GetPad(0)->GetLeftMouseJustDown())
-				MouseButtonJustClicked = 1;
+				MouseButtonJustClicked = rsMOUSELEFTBUTTON;
 			else if (CPad::GetPad(0)->GetRightMouseJustUp())
-				MouseButtonJustClicked = 3;
+				MouseButtonJustClicked = rsMOUSERIGHTBUTTON;
 			else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
-				MouseButtonJustClicked = 2;
+				MouseButtonJustClicked = rsMOUSMIDDLEBUTTON;
 			else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
-				MouseButtonJustClicked = 4;
+				MouseButtonJustClicked = rsMOUSEWHEELUPBUTTON;
 			else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
-				MouseButtonJustClicked = 5;
+				MouseButtonJustClicked = rsMOUSEWHEELDOWNBUTTON;
 			else if (CPad::GetPad(0)->GetMouseX1JustUp())
-				MouseButtonJustClicked = 6;
+				MouseButtonJustClicked = rsMOUSEX1BUTTON;
 			else if (CPad::GetPad(0)->GetMouseX2JustUp())
-				MouseButtonJustClicked = 7;
+				MouseButtonJustClicked = rsMOUSEX2BUTTON;
 
 			JoyButtonJustClicked = ControlsManager.GetJoyButtonJustDown();
 
@@ -4796,6 +4817,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
 					TheCamera.m_bUseMouse3rdPerson = false;
 #endif
 					SaveSettings();
+#ifdef LOAD_INI_SETTINGS
+					SaveINIControllerSettings();
+#endif
 				}
 				SetHelperText(2);
 				break;
@@ -4826,7 +4850,8 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
 
 					*option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
 
-					if (option.m_CFOSelect->save)
+					// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
+					// if (option.m_CFOSelect->save)
 						SaveSettings();
 
 					if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
@@ -4982,7 +5007,8 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
 
 						*option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
 
-						if (option.m_CFOSelect->save)
+						// Now everything is saved in .ini, and LOAD_INI_SETTINGS is fundamental for CFO
+						// if (option.m_CFOSelect->save)
 							SaveSettings();
 
 						if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 4a812b05..c1c3983e 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -392,6 +392,7 @@ struct CCustomScreenLayout {
 struct CCFO
 {
 	int8 *value;
+	const char *saveCat;
 	const char *save;
 };
 
@@ -406,11 +407,12 @@ struct CCFOSelect : CCFO
 	bool disableIfGameLoaded;
 
 	CCFOSelect() {};
-	CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc = nil, bool disableIfGameLoaded = false){
+	CCFOSelect(int8* value, const char* saveCat, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc = nil, bool disableIfGameLoaded = false){
 		this->value = value;
 		if (value)
 			this->lastSavedValue = this->displayedValue = *value;
 
+		this->saveCat = saveCat;
 		this->save = save;
 		this->rightTexts = (char**)rightTexts;
 		this->numRightTexts = numRightTexts;
@@ -426,8 +428,9 @@ struct CCFODynamic : CCFO
 	ButtonPressFunc buttonPressFunc;
 
 	CCFODynamic() {};
-	CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){
+	CCFODynamic(int8* value, const char* saveCat, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){
 		this->value = value;
+		this->saveCat = saveCat;
 		this->save = save;
 		this->drawFunc = drawFunc;
 		this->buttonPressFunc = buttonPressFunc;
@@ -581,7 +584,7 @@ public:
 	int8 m_bLanguageLoaded;
 	uint8 m_PrefsAllowNastyGame;
 	int8 m_PrefsMP3BoostVolume;
-	uint8 m_ControlMethod;
+	int8 m_ControlMethod;
 	int32 m_nPrefsVideoMode;
 	int32 m_nDisplayVideoMode;
 	int32 m_nMouseTempPosX;
diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp
index 70c92ce8..d34ff8b9 100644
--- a/src/core/MenuScreensCustom.cpp
+++ b/src/core/MenuScreensCustom.cpp
@@ -24,51 +24,51 @@
 #ifdef CUSTOM_FRONTEND_OPTIONS
 
 #ifdef IMPROVED_VIDEOMODE
-	#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange, true) }, 0, 0, MENUALIGN_LEFT,
+	#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define VIDEOMODE_SELECTOR
 #endif
 
 #ifdef MULTISAMPLING
-	#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT,
+	#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define MULTISAMPLING_SELECTOR
 #endif
 
 #ifdef CUTSCENE_BORDERS_SWITCH
-	#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
+	#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define CUTSCENE_BORDERS_TOGGLE
 #endif
 
 #ifdef FREE_CAM
-	#define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
+	#define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define FREE_CAM_TOGGLE
 #endif
 
 #ifdef PS2_ALPHA_TEST
-	#define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
+	#define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define DUALPASS_SELECTOR 
 #endif
 
 #ifdef NO_ISLAND_LOADING
-	#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT,
+	#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define ISLAND_LOADING_SELECTOR 
 #endif
 
 #ifdef EXTENDED_COLOURFILTER
 	#define POSTFX_SELECTORS \
-		MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, 0, 0, MENUALIGN_LEFT, \
-		MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
+		MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, 0, 0, MENUALIGN_LEFT, \
+		MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) }, 0, 0, MENUALIGN_LEFT,
 #else
 	#define POSTFX_SELECTORS
 #endif	
 
 #ifdef INVERT_LOOK_FOR_PAD
-	#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false) }, 150, 0, MENUALIGN_LEFT,
+	#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) }, 150, 0, MENUALIGN_LEFT,
 #else
 	#define INVERT_PAD_SELECTOR
 #endif
@@ -388,7 +388,7 @@ CMenuScreenCustom aScreens[] = {
 		MENUACTION_RADARMODE,	"FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
 		MENUACTION_HUD,			"FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
 		MENUACTION_SUBTITLES,	"FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
-		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER,
+		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) }, 320, 0, MENUALIGN_CENTER,
 		MENUACTION_GOBACK,		"FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
 	},
 #endif
@@ -401,9 +401,9 @@ CMenuScreenCustom aScreens[] = {
 		MENUACTION_LANG_ITA,	"FEL_ITA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
 		MENUACTION_LANG_SPA,    "FEL_SPA", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
 #ifdef MORE_LANGUAGES
-		MENUACTION_CFO_DYNAMIC,    "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER,
-		MENUACTION_CFO_DYNAMIC,    "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER
-		MENUACTION_CFO_DYNAMIC,    "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER,
+		MENUACTION_CFO_DYNAMIC,    "FEL_POL", { new CCFODynamic(nil, nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER,
+		MENUACTION_CFO_DYNAMIC,    "FEL_RUS", { new CCFODynamic(nil, nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER
+		MENUACTION_CFO_DYNAMIC,    "FEL_JAP", { new CCFODynamic(nil, nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER,
 #endif
 		MENUACTION_GOBACK,		"FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
 	},
@@ -695,7 +695,7 @@ CMenuScreenCustom aScreens[] = {
 		MENUACTION_TRAILS,		"FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
 #endif
 		// re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
-		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER,
+		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER,
 		MENUACTION_GOBACK,		"FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
 	},
 #endif
@@ -705,7 +705,7 @@ CMenuScreenCustom aScreens[] = {
 	{ "FEC_JOD", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({0, 0, 0, false, false, 30}), nil,
 
 		MENUACTION_LABEL,	"FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0,
-		MENUACTION_CFO_DYNAMIC,	"FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) }, 80, 200, MENUALIGN_LEFT,
+		MENUACTION_CFO_DYNAMIC,	"FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) }, 80, 200, MENUALIGN_LEFT,
 		MENUACTION_GOBACK,		"FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER,
 	},
 #endif
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 671a4552..5c79c0d3 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -61,7 +61,7 @@ bool CPad::bOldDisplayNoControllerMessage;
 bool CPad::m_bMapPadOneToPadTwo;
 bool CPad::m_bDebugCamPCOn;
 bool CPad::bHasPlayerCheated;
-bool CPad::bInvertLook4Pad = true;
+bool CPad::bInvertLook4Pad;
 #ifdef GTA_PS2
 unsigned char act_direct[6];
 unsigned char act_align[6];
diff --git a/src/core/main.h b/src/core/main.h
index 37a82fb2..eacfd8e1 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -47,6 +47,8 @@ void TheModelViewer(void);
 #ifdef LOAD_INI_SETTINGS
 void LoadINISettings();
 void SaveINISettings();
+void LoadINIControllerSettings();
+void SaveINIControllerSettings();
 #endif
 
 #ifdef NEW_RENDERER
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 7b3ab10c..8ec1bd01 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -33,10 +33,9 @@
 #include "custompipes.h"
 #include "MemoryHeap.h"
 #include "FileMgr.h"
-
-#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
+#include "Camera.h"
+#include "MBlur.h"
 #include "ControllerConfig.h"
-#endif
 
 #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
 #include "crossplatform.h"
@@ -96,16 +95,16 @@ CustomFrontendOptionsPopulate(void)
 	if (fd) {
 #ifdef GRAPHICS_MENU_OPTIONS
 		FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
-		FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
-		FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
-		FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
-		FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
+		FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
+		FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
+		FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
+		FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
 #else
 		FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false);
-		FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
-		FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
-		FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
-		FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
+		FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
+		FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
+		FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
+		FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
 #endif
 		CFileMgr::CloseFile(fd);
 	}
@@ -118,53 +117,298 @@ CustomFrontendOptionsPopulate(void)
 #include "ini_parser.hpp"
 
 linb::ini cfg;
-int CheckAndReadIniInt(const char *cat, const char *key, int original)
+bool ReadIniIfExists(const char *cat, const char *key, uint32 *out)
 {
-	std::string strval = cfg.get(cat, key, "");
+	std::string strval = cfg.get(cat, key, "\xBA");
 	const char *value = strval.c_str();
-	if (value && value[0] != '\0')
-		return atoi(value);
-
-	return original;
+	char *endPtr;
+	if (value && value[0] != '\xBA') {
+		*out = strtoul(value, &endPtr, 0);
+		return true;
+	}
+	return false;
 }
 
-float CheckAndReadIniFloat(const char *cat, const char *key, float original)
+bool ReadIniIfExists(const char *cat, const char *key, bool *out)
 {
-	std::string strval = cfg.get(cat, key, "");
+	std::string strval = cfg.get(cat, key, "\xBA");
 	const char *value = strval.c_str();
-	if (value && value[0] != '\0')
-		return atof(value);
-
-	return original;
+	char *endPtr;
+	if (value && value[0] != '\xBA') {
+		*out = strtoul(value, &endPtr, 0);
+		return true;
+	}
+	return false;
 }
 
-void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed)
+bool ReadIniIfExists(const char *cat, const char *key, int32 *out)
+{
+	std::string strval = cfg.get(cat, key, "\xBA");
+	const char *value = strval.c_str();
+	char *endPtr;
+	if (value && value[0] != '\xBA') {
+		*out = strtol(value, &endPtr, 0);
+		return true;
+	}
+	return false;
+}
+
+bool ReadIniIfExists(const char *cat, const char *key, int8 *out)
+{
+	std::string strval = cfg.get(cat, key, "\xBA");
+	const char *value = strval.c_str();
+	char *endPtr;
+	if (value && value[0] != '\xBA') {
+		*out = strtol(value, &endPtr, 0);
+		return true;
+	}
+	return false;
+}
+
+bool ReadIniIfExists(const char *cat, const char *key, float *out)
+{
+	std::string strval = cfg.get(cat, key, "\xBA");
+	const char *value = strval.c_str();
+	if (value && value[0] != '\xBA') {
+		*out = atof(value);
+		return true;
+	}
+	return false;
+}
+
+bool ReadIniIfExists(const char *cat, const char *key, char *out, int size)
+{
+	std::string strval = cfg.get(cat, key, "\xBA");
+	const char *value = strval.c_str();
+	if (value && value[0] != '\xBA') {
+		strncpy(out, value, size);
+		return true;
+	}
+	return false;
+}
+
+void StoreIni(const char *cat, const char *key, uint32 val)
 {
 	char temp[10];
-	if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
-		changed = true;
-		sprintf(temp, "%u", val);
-		cfg.set(cat, key, temp);
+sprintf(temp, "%u", val);
+	cfg.set(cat, key, temp);
+}
+
+void StoreIni(const char *cat, const char *key, uint8 val)
+{
+	char temp[10];
+	sprintf(temp, "%u", (uint32)val);
+	cfg.set(cat, key, temp);
+}
+
+void StoreIni(const char *cat, const char *key, int32 val)
+{
+	char temp[10];
+	sprintf(temp, "%d", val);
+	cfg.set(cat, key, temp);
+}
+
+void StoreIni(const char *cat, const char *key, int8 val)
+{
+	char temp[10];
+	sprintf(temp, "%d", (int32)val);
+	cfg.set(cat, key, temp);
+}
+
+void StoreIni(const char *cat, const char *key, float val)
+{
+	char temp[10];
+	sprintf(temp, "%f", val);
+	cfg.set(cat, key, temp);
+}
+
+void StoreIni(const char *cat, const char *key, char *val, int size)
+{
+	cfg.set(cat, key, val);
+}
+
+const char *iniControllerActions[] = { "PED_FIREWEAPON", "PED_CYCLE_WEAPON_RIGHT", "PED_CYCLE_WEAPON_LEFT", "GO_FORWARD", "GO_BACK", "GO_LEFT", "GO_RIGHT", "PED_SNIPER_ZOOM_IN",
+	"PED_SNIPER_ZOOM_OUT", "VEHICLE_ENTER_EXIT", "CAMERA_CHANGE_VIEW_ALL_SITUATIONS", "PED_JUMPING", "PED_SPRINT", "PED_LOOKBEHIND", "PED_DUCK", "PED_ANSWER_PHONE", 
+#ifdef BIND_VEHICLE_FIREWEAPON
+	"VEHICLE_FIREWEAPON",
+#endif
+	"VEHICLE_ACCELERATE", "VEHICLE_BRAKE", "VEHICLE_CHANGE_RADIO_STATION", "VEHICLE_HORN", "TOGGLE_SUBMISSIONS", "VEHICLE_HANDBRAKE", "PED_1RST_PERSON_LOOK_LEFT",
+	"PED_1RST_PERSON_LOOK_RIGHT", "VEHICLE_LOOKLEFT", "VEHICLE_LOOKRIGHT", "VEHICLE_LOOKBEHIND", "VEHICLE_TURRETLEFT", "VEHICLE_TURRETRIGHT", "VEHICLE_TURRETUP", "VEHICLE_TURRETDOWN",
+	"PED_CYCLE_TARGET_LEFT", "PED_CYCLE_TARGET_RIGHT", "PED_CENTER_CAMERA_BEHIND_PLAYER", "PED_LOCK_TARGET", "NETWORK_TALK", "PED_1RST_PERSON_LOOK_UP", "PED_1RST_PERSON_LOOK_DOWN",
+	"_CONTROLLERACTION_36", "TOGGLE_DPAD", "SWITCH_DEBUG_CAM_ON", "TAKE_SCREEN_SHOT", "SHOW_MOUSE_POINTER_TOGGLE", "UNKNOWN_ACTION" };
+
+const char *iniControllerTypes[] = { "kbd:", "2ndKbd:", "mouse:", "joy:" };
+
+const char *iniMouseButtons[] = {"LEFT","MIDDLE","RIGHT","WHLUP","WHLDOWN","X1","X2"};
+
+const char *iniKeyboardButtons[] = {"ESC","F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12",
+	"INS","DEL","HOME","END","PGUP","PGDN","UP","DOWN","LEFT","RIGHT","DIVIDE","TIMES","PLUS","MINUS","PADDEL",
+	"PADEND","PADDOWN","PADPGDN","PADLEFT","PAD5","NUMLOCK","PADRIGHT","PADHOME","PADUP","PADPGUP","PADINS",
+	"PADENTER", "SCROLL","PAUSE","BACKSP","TAB","CAPSLK","ENTER","LSHIFT","RSHIFT","SHIFT","LCTRL","RCTRL","LALT",
+	"RALT", "LWIN", "RWIN", "APPS", "NULL"};
+
+void LoadINIControllerSettings()
+{
+	for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) {
+		char value[128];
+		if (ReadIniIfExists("Bindings", iniControllerActions[i], value, 128)) {
+			for (int32 j = 0; j < MAX_CONTROLLERTYPES; j++){
+				ControlsManager.ClearSettingsAssociatedWithAction((e_ControllerAction)i, (eControllerType)j);
+			}
+
+			for (char *binding = strtok(value,", "); binding != nil; binding = strtok(nil, ", ")) {
+				int contType = -1;
+				for (int32 k = 0; k < ARRAY_SIZE(iniControllerTypes); k++) {
+					int len = strlen(iniControllerTypes[k]);
+					if (strncmp(binding, iniControllerTypes[k], len) == 0) {
+						contType = k;
+						binding += len;
+						break;
+					}
+				}
+				if (contType == -1)
+					continue;
+
+				int contKey;
+				if (contType == JOYSTICK) {
+					char *temp;
+					contKey = strtol(binding, &temp, 0);
+
+				} else if (contType == KEYBOARD || contType == OPTIONAL_EXTRA) {
+					if (strlen(binding) == 1) {
+						contKey = binding[0];
+					} else if(strcmp(binding, "SPC") == 0) {
+						contKey = ' ';
+					} else {
+						for (int32 k = 0; k < ARRAY_SIZE(iniKeyboardButtons); k++) {
+							if(strcmp(binding, iniKeyboardButtons[k]) == 0) {
+								contKey = 1000 + k;
+								break;
+							}
+						}
+					}
+				} else if (contType == MOUSE) {
+					for (int32 k = 0; k < ARRAY_SIZE(iniMouseButtons); k++) {
+						if(strcmp(binding, iniMouseButtons[k]) == 0) {
+							contKey = 1 + k;
+							break;
+						}
+					}
+				}
+
+				ControlsManager.SetControllerKeyAssociatedWithAction((e_ControllerAction)i, contKey, (eControllerType)contType);
+			}
+		}
 	}
 }
 
-void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed)
+void SaveINIControllerSettings()
 {
-	char temp[10];
-	if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
-		changed = true;
-		sprintf(temp, "%f", val);
-		cfg.set(cat, key, temp);
+	for (int32 i = 0; i < MAX_CONTROLLERACTIONS; i++) {
+		char value[128] = { '\0' };
+
+		// upper limit should've been GetNumOfSettingsForAction(i), but sadly even R* doesn't use it's own system correctly, and there are gaps between orders.
+		for (int32 j = SETORDER_1; j < MAX_SETORDERS; j++){
+
+			// We respect the m_ContSetOrder, and join/implode/order the bindings according to that; using comma as seperator.
+			for (int32 k = 0; k < MAX_CONTROLLERTYPES; k++){
+				if (ControlsManager.m_aSettings[i][k].m_ContSetOrder == j) {
+					char next[32];
+					if (k == JOYSTICK) {
+						snprintf(next, 32, "%s%d,", iniControllerTypes[k], ControlsManager.m_aSettings[i][k].m_Key);
+
+					} else if (k == KEYBOARD || k == OPTIONAL_EXTRA) {
+						if (ControlsManager.m_aSettings[i][k].m_Key == ' ')
+							snprintf(next, 32, "%sSPC,", iniControllerTypes[k]);
+						else if (ControlsManager.m_aSettings[i][k].m_Key < 256)
+							snprintf(next, 32, "%s%c,", iniControllerTypes[k], ControlsManager.m_aSettings[i][k].m_Key);
+						else
+							snprintf(next, 32, "%s%s,", iniControllerTypes[k], iniKeyboardButtons[ControlsManager.m_aSettings[i][k].m_Key - 1000]);
+
+					} else if (k == MOUSE) {
+						snprintf(next, 32, "%s%s,", iniControllerTypes[k], iniMouseButtons[ControlsManager.m_aSettings[i][k].m_Key - 1]);
+					}
+					strcat(value, next);
+					break;
+				}
+			}
+		}
+		int len = strlen(value);
+		if (len > 0)
+			value[len - 1] = '\0'; // to remove comma
+
+		StoreIni("Bindings", iniControllerActions[i], value, 128);
 	}
+
+	cfg.write_file("re3.ini");
 }
 
 void LoadINISettings()
 {
 	cfg.load_file("reVC.ini");
 
+#ifdef IMPROVED_VIDEOMODE
+	ReadIniIfExists("VideoMode", "Width", &FrontEndMenuManager.m_nPrefsWidth);
+	ReadIniIfExists("VideoMode", "Height", &FrontEndMenuManager.m_nPrefsHeight);
+	ReadIniIfExists("VideoMode", "Depth", &FrontEndMenuManager.m_nPrefsDepth);
+	ReadIniIfExists("VideoMode", "Subsystem", &FrontEndMenuManager.m_nPrefsSubsystem);
+	// Windowed mode is loaded below in CUSTOM_FRONTEND_OPTIONS section
+#else
+	ReadIniIfExists("Graphics", "VideoMode", &FrontEndMenuManager.m_nDisplayVideoMode);
+#endif
+	ReadIniIfExists("Controller", "HeadBob1stPerson", &TheCamera.m_bHeadBob);
+	ReadIniIfExists("Controller", "HorizantalMouseSens", &TheCamera.m_fMouseAccelHorzntl);
+	ReadIniIfExists("Controller", "InvertMouseVertically", &MousePointerStateHelper.bInvertVertically);
+	ReadIniIfExists("Controller", "DisableMouseSteering", &CVehicle::m_bDisableMouseSteering);
+	ReadIniIfExists("Audio", "SfxVolume", &FrontEndMenuManager.m_PrefsSfxVolume);
+	ReadIniIfExists("Audio", "MusicVolume", &FrontEndMenuManager.m_PrefsMusicVolume);
+	ReadIniIfExists("Audio", "MP3BoostVolume", &FrontEndMenuManager.m_PrefsMP3BoostVolume);
+	ReadIniIfExists("Audio", "Radio", &FrontEndMenuManager.m_PrefsRadioStation);
+	ReadIniIfExists("Audio", "SpeakerType", &FrontEndMenuManager.m_PrefsSpeakers);
+	ReadIniIfExists("Audio", "Provider", &FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
+	ReadIniIfExists("Audio", "DynamicAcoustics", &FrontEndMenuManager.m_PrefsDMA);
+	ReadIniIfExists("Display", "Brightness", &FrontEndMenuManager.m_PrefsBrightness);
+	ReadIniIfExists("Display", "DrawDistance", &FrontEndMenuManager.m_PrefsLOD);
+	ReadIniIfExists("Display", "Subtitles", &FrontEndMenuManager.m_PrefsShowSubtitles);
+	ReadIniIfExists("Graphics", "AspectRatio", &FrontEndMenuManager.m_PrefsUseWideScreen);
+	ReadIniIfExists("Graphics", "FrameLimiter", &FrontEndMenuManager.m_PrefsFrameLimiter);
+#ifdef LEGACY_MENU_OPTIONS
+	ReadIniIfExists("Graphics", "VSync", &FrontEndMenuManager.m_PrefsVsyncDisp);
+	ReadIniIfExists("Graphics", "Trails", &CMBlur::BlurOn);
+#endif
+	ReadIniIfExists("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256);
+	ReadIniIfExists("Controller", "Method", &FrontEndMenuManager.m_ControlMethod);
+	ReadIniIfExists("General", "Language", &FrontEndMenuManager.m_PrefsLanguage);
+	ReadIniIfExists("Display", "ShowHud", &FrontEndMenuManager.m_PrefsShowHud);
+	ReadIniIfExists("Display", "RadarMode", &FrontEndMenuManager.m_PrefsRadarMode);
+	ReadIniIfExists("Display", "ShowLegends", &FrontEndMenuManager.m_PrefsShowLegends);
+
+#ifdef EXTENDED_COLOURFILTER
+	ReadIniIfExists("CustomPipesValues", "PostFXIntensity", &CPostFX::Intensity);
+#endif
+#ifdef EXTENDED_PIPELINES
+	ReadIniIfExists("CustomPipesValues", "NeoVehicleShininess", &CustomPipes::VehicleShininess);
+	ReadIniIfExists("CustomPipesValues", "NeoVehicleSpecularity", &CustomPipes::VehicleSpecularity);
+	ReadIniIfExists("CustomPipesValues", "RimlightMult", &CustomPipes::RimlightMult);
+	ReadIniIfExists("CustomPipesValues", "LightmapMult", &CustomPipes::LightmapMult);
+	ReadIniIfExists("CustomPipesValues", "GlossMult", &CustomPipes::GlossMult);
+#endif
+
+#ifdef PROPER_SCALING
+	ReadIniIfExists("Draw", "ProperScaling", &CDraw::ms_bProperScaling);	
+#endif
+#ifdef FIX_RADAR
+	ReadIniIfExists("Draw", "FixRadar", &CDraw::ms_bFixRadar);	
+#endif
+#ifdef FIX_SPRITES
+	ReadIniIfExists("Draw", "FixSprites", &CDraw::ms_bFixSprites);	
+#endif
+
 #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
 	// Written by assuming the codes below will run after _InputInitialiseJoys().
-	strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str());
+	std::string strval = cfg.get("Controller", "JoystickName", "");
+	const char *value = strval.c_str();
+	strcpy(gSelectedJoystickName, value);
 	
 	if(gSelectedJoystickName[0] != '\0') {
 		for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
@@ -187,6 +431,7 @@ void LoadINISettings()
 					CFileMgr::CloseFile(gta3set);
 				}
 				CFileMgr::SetDir("");
+				// We call LoadINIControllerSettings after this func., so calling here isn't needed
 				break;
 			}
 		}
@@ -203,7 +448,7 @@ void LoadINISettings()
 			// CFO check
 			if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
 				// CFO only supports saving uint8 right now
-				*option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value);
+				ReadIniIfExists(option.m_CFO->saveCat, option.m_CFO->save, option.m_CFO->value);
 				if (option.m_Action == MENUACTION_CFO_SELECT) {
 					option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value;
 				}
@@ -211,39 +456,70 @@ void LoadINISettings()
 		}
 	}
 #endif
-
-#ifdef EXTENDED_COLOURFILTER
-	CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
-#endif
-#ifdef EXTENDED_PIPELINES
-	CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess);
-	CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity);
-	CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult);
-	CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
-	CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
-#endif
-	gBackfaceCulling = CheckAndReadIniInt("Rendering", "BackfaceCulling", gBackfaceCulling);
-	
-#ifdef PROPER_SCALING
-	CDraw::ms_bProperScaling = CheckAndReadIniInt("Draw", "ProperScaling", CDraw::ms_bProperScaling);	
-#endif
-#ifdef FIX_RADAR
-	CDraw::ms_bFixRadar      = CheckAndReadIniInt("Draw", "FixRadar", CDraw::ms_bFixRadar);	
-#endif
-#ifdef FIX_SPRITES
-	CDraw::ms_bFixSprites    = CheckAndReadIniInt("Draw", "FixSprites", CDraw::ms_bFixSprites);	
-#endif
 }
 
 void SaveINISettings()
 {
-	bool changed = false;
+#ifdef IMPROVED_VIDEOMODE
+	StoreIni("VideoMode", "Width", FrontEndMenuManager.m_nPrefsWidth);
+	StoreIni("VideoMode", "Height", FrontEndMenuManager.m_nPrefsHeight);
+	StoreIni("VideoMode", "Depth", FrontEndMenuManager.m_nPrefsDepth);
+	StoreIni("VideoMode", "Subsystem", FrontEndMenuManager.m_nPrefsSubsystem);
+	// Windowed mode is loaded below in CUSTOM_FRONTEND_OPTIONS section
+#else
+	StoreIni("Graphics", "VideoMode", FrontEndMenuManager.m_nDisplayVideoMode);
+#endif
+	StoreIni("Controller", "HeadBob1stPerson", TheCamera.m_bHeadBob);
+	StoreIni("Controller", "HorizantalMouseSens", TheCamera.m_fMouseAccelHorzntl);
+	StoreIni("Controller", "InvertMouseVertically", MousePointerStateHelper.bInvertVertically);
+	StoreIni("Controller", "DisableMouseSteering", CVehicle::m_bDisableMouseSteering);
+	StoreIni("Audio", "SfxVolume", FrontEndMenuManager.m_PrefsSfxVolume);
+	StoreIni("Audio", "MusicVolume", FrontEndMenuManager.m_PrefsMusicVolume);
+	StoreIni("Audio", "MP3BoostVolume", FrontEndMenuManager.m_PrefsMP3BoostVolume);
+	StoreIni("Audio", "Radio", FrontEndMenuManager.m_PrefsRadioStation);
+	StoreIni("Audio", "SpeakerType", FrontEndMenuManager.m_PrefsSpeakers);
+	StoreIni("Audio", "Provider", FrontEndMenuManager.m_nPrefsAudio3DProviderIndex);
+	StoreIni("Audio", "DynamicAcoustics", FrontEndMenuManager.m_PrefsDMA);
+	StoreIni("Display", "Brightness", FrontEndMenuManager.m_PrefsBrightness);
+	StoreIni("Display", "DrawDistance", FrontEndMenuManager.m_PrefsLOD);
+	StoreIni("Display", "Subtitles", FrontEndMenuManager.m_PrefsShowSubtitles);
+	StoreIni("Graphics", "AspectRatio", FrontEndMenuManager.m_PrefsUseWideScreen);
+#ifdef LEGACY_MENU_OPTIONS
+	StoreIni("Graphics", "VSync", FrontEndMenuManager.m_PrefsVsyncDisp);
+	StoreIni("Graphics", "Trails", CMBlur::BlurOn);
+#endif
+	StoreIni("Graphics", "FrameLimiter", FrontEndMenuManager.m_PrefsFrameLimiter);
+	StoreIni("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256);
+	StoreIni("Controller", "Method", FrontEndMenuManager.m_ControlMethod);
+	StoreIni("General", "Language", FrontEndMenuManager.m_PrefsLanguage);
+	StoreIni("Display", "ShowHud", FrontEndMenuManager.m_PrefsShowHud);
+	StoreIni("Display", "RadarMode", FrontEndMenuManager.m_PrefsRadarMode);
+	StoreIni("Display", "ShowLegends", FrontEndMenuManager.m_PrefsShowLegends);
+
+#ifdef EXTENDED_COLOURFILTER
+	StoreIni("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
+#endif
+#ifdef EXTENDED_PIPELINES
+	StoreIni("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess);
+	StoreIni("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity);
+	StoreIni("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult);
+	StoreIni("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
+	StoreIni("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
+#endif
+	StoreIni("Rendering", "BackfaceCulling", gBackfaceCulling);
+
+#ifdef PROPER_SCALING	
+	StoreIni("Draw", "ProperScaling", CDraw::ms_bProperScaling);	
+#endif
+#ifdef FIX_RADAR
+	StoreIni("Draw", "FixRadar", CDraw::ms_bFixRadar);
+#endif
+#ifdef FIX_SPRITES
+	StoreIni("Draw", "FixSprites", CDraw::ms_bFixSprites);	
+#endif
 
 #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
-	if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) {
-		changed = true;
-		cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName);
-	}
+	StoreIni("Controller", "JoystickName", gSelectedJoystickName, 128);
 #endif
 #ifdef CUSTOM_FRONTEND_OPTIONS
 	for (int i = 0; i < MENUPAGES; i++) {
@@ -254,36 +530,13 @@ void SaveINISettings()
 				
 			if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
 				// Beware: CFO only supports saving uint8 right now
-				CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed);
+				StoreIni(option.m_CFO->saveCat, option.m_CFO->save, *option.m_CFO->value);
 			}
 		}
 	}
 #endif
 
-#ifdef EXTENDED_COLOURFILTER
-	CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed);
-#endif
-#ifdef EXTENDED_PIPELINES
-	CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed);
-	CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed);
-	CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed);
-	CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed);
-	CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed);
-#endif
-	CheckAndSaveIniInt("Rendering", "BackfaceCulling", gBackfaceCulling, changed);
-
-#ifdef PROPER_SCALING	
-	CheckAndSaveIniInt("Draw", "ProperScaling", CDraw::ms_bProperScaling, changed);	
-#endif
-#ifdef FIX_RADAR
-	CheckAndSaveIniInt("Draw", "FixRadar", CDraw::ms_bFixRadar, changed);
-#endif
-#ifdef FIX_SPRITES
-	CheckAndSaveIniInt("Draw", "FixSprites", CDraw::ms_bFixSprites, changed);	
-#endif
-
-	if (changed)
-		cfg.write_file("reVC.ini");
+	cfg.write_file("reVC.ini");
 }
 
 #endif
diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp
index 8a95a49a..2660e75e 100644
--- a/src/extras/frontendoption.cpp
+++ b/src/extras/frontendoption.cpp
@@ -111,7 +111,7 @@ void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint
 	option.m_TargetMenu = targetMenu;
 }
 
-void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName, bool disableIfGameLoaded)
+void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat, const char* saveName, bool disableIfGameLoaded)
 {	
 	int8 screenOptionOrder = RegisterNewOption();
 
@@ -130,13 +130,14 @@ void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align
 		option.m_CFOSelect->displayedValue = *var;
 		option.m_CFOSelect->lastSavedValue = *var;
 	}
+	option.m_CFOSelect->saveCat = saveCat;
 	option.m_CFOSelect->save = saveName;
 	option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter;
 	option.m_CFOSelect->changeFunc = changeFunc;
 	option.m_CFOSelect->disableIfGameLoaded = disableIfGameLoaded;
 }
 
-void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName)
+void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat, const char* saveName)
 {
 	int8 screenOptionOrder = RegisterNewOption();
 
@@ -150,6 +151,7 @@ void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 alig
 	option.m_CFODynamic->drawFunc = drawFunc;
 	option.m_CFODynamic->buttonPressFunc = buttonPressFunc;
 	option.m_CFODynamic->value = var;
+	option.m_CFODynamic->saveCat = saveCat;
 	option.m_CFODynamic->save = saveName;
 }
 
diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h
index 2719f076..05cd5fa0 100644
--- a/src/extras/frontendoption.h
+++ b/src/extras/frontendoption.h
@@ -76,10 +76,10 @@ uint8 GetNumberOfMenuOptions(int screen);
 
 void FrontendOptionSetCursor(int screen, int8 option, bool overwrite = false);
 
-// var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to saveName param. obv), otherwise pass nil/0
+// var is optional in AddDynamic, enables you to save them in an INI file(also needs passing char array to saveCat and saveKey param. obv), otherwise pass nil/0
 void FrontendOptionAddBuiltinAction(const char* gxtKey, uint16 x, uint16 y, uint8 align, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE);
-void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName = nil, bool disableIfGameLoaded = false);
-void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = nil);
+void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat = nil, const char* saveKey = nil, bool disableIfGameLoaded = false);
+void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat = nil, const char* saveKey = nil);
 
 // lineHeight = 0 means game will use MENU_DEFAULT_LINE_HEIGHT
 uint8 FrontendScreenAdd(const char* gxtKey, int prevPage, int lineHeight, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil);
diff --git a/src/render/WaterCreatures.cpp b/src/render/WaterCreatures.cpp
index 01f241b3..92fb74ee 100644
--- a/src/render/WaterCreatures.cpp
+++ b/src/render/WaterCreatures.cpp
@@ -6,6 +6,7 @@
 #include "Camera.h"
 #include "PlayerPed.h"
 #include "General.h"
+#include "Object.h"
 
 int CWaterCreatures::nNumActiveSeaLifeForms;
 CWaterCreature CWaterCreatures::aWaterCreatures[NUM_WATER_CREATURES];
diff --git a/src/render/WaterCreatures.h b/src/render/WaterCreatures.h
index 9ef8198c..32754a10 100644
--- a/src/render/WaterCreatures.h
+++ b/src/render/WaterCreatures.h
@@ -1,5 +1,6 @@
 #pragma once
-#include "Object.h"
+
+class CObject;
 
 enum eFishSlotState {
 	WATER_CREATURE_INIT = 0,
diff --git a/src/save/GenericGameStorage.cpp b/src/save/GenericGameStorage.cpp
index ee946480..54685b66 100644
--- a/src/save/GenericGameStorage.cpp
+++ b/src/save/GenericGameStorage.cpp
@@ -345,7 +345,11 @@ GenericLoad()
 #endif
 	ReadDataFromBufferPointer(buf, CGame::currArea);
 	ReadDataFromBufferPointer(buf, CVehicle::bAllTaxisHaveNitro);
+#ifdef LOAD_INI_SETTINGS
 	buf += align4bytes(sizeof(CPad::bInvertLook4Pad));
+#else
+	ReadDataFromBufferPointer(buf, CPad::bInvertLook4Pad);
+#endif
 	ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColour);
 	ReadDataFromBufferPointer(buf, CTimeCycle::m_bExtraColourOn);
 	ReadDataFromBufferPointer(buf, CTimeCycle::m_ExtraColourInter);
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 8c9289d2..a86ccaf8 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -1634,6 +1634,7 @@ main(int argc, char *argv[])
 	SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &NewStickyKeys, SPIF_SENDCHANGE);
 #endif
 
+	// This part is needed because controller initialisation overwrites loaded settings.
 	{
 		CFileMgr::SetDirMyDocuments();
 		
@@ -1646,6 +1647,10 @@ main(int argc, char *argv[])
 		}
 		
 		CFileMgr::SetDir("");
+
+#ifdef LOAD_INI_SETTINGS
+		LoadINIControllerSettings();
+#endif
 	}
 	
 #ifdef _WIN32
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index 242a3fe2..02b3f917 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -2142,6 +2142,7 @@ WinMain(HINSTANCE instance,
 	ShowWindow(PSGLOBAL(window), cmdShow);
 	UpdateWindow(PSGLOBAL(window));
 	
+	// This part is needed because controller initialisation overwrites loaded settings.
 	{
 		CFileMgr::SetDirMyDocuments();
 		
@@ -2154,6 +2155,10 @@ WinMain(HINSTANCE instance,
 		}
 		
 		CFileMgr::SetDir("");
+
+#ifdef LOAD_INI_SETTINGS
+		LoadINIControllerSettings();
+#endif
 	}
 	
 	SetErrorMode(SEM_FAILCRITICALERRORS);