diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index 37421904..94143746 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -13,6 +13,7 @@
 #include "World.h"
 #include "Zones.h"
 #include "sampman.h"
+#include "Wanted.h"
 
 const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
 const int policeChannel = channels + 1;
diff --git a/src/audio/PoliceRadio.h b/src/audio/PoliceRadio.h
index c01f21ce..368708b6 100644
--- a/src/audio/PoliceRadio.h
+++ b/src/audio/PoliceRadio.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Wanted.h"
+#include "Crime.h"
 
 struct cAMCrime {
 	int32 type;
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index 72c3eb7f..a5f6c7e2 100644
--- a/src/audio/sampman.h
+++ b/src/audio/sampman.h
@@ -1,5 +1,4 @@
 #pragma once
-#include "common.h"
 #include "AudioSamples.h"
 
 #define MAX_VOLUME 127
diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp
index db38da64..82886c66 100644
--- a/src/audio/sampman_miles.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -1,8 +1,5 @@
-#include "common.h"
-
 #ifdef AUDIO_MSS
-#include <windows.h>
-#include <shobjidl.h>
+#include <shlobj.h>
 #include <shlguid.h>
 
 #include <time.h>
@@ -11,6 +8,7 @@
 #include "eax-util.h"
 #include "mss.h"
 
+#include "common.h"
 #include "sampman.h"
 #include "AudioManager.h"
 #include "MusicManager.h"
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index bb7f0aac..798ea287 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -1,17 +1,11 @@
 //#define JUICY_OAL
 
 #ifdef AUDIO_OAL
-#include "sampman.h"
-
 #include <time.h>
 
 #include "eax.h"
 #include "eax-util.h"
 
-#define WITHWINDOWS
-#include "common.h"
-#include "crossplatform.h"
-
 #ifdef _WIN32
 #include <io.h>
 #include <AL/al.h>
@@ -19,8 +13,22 @@
 #include <AL/alext.h>
 #include <AL/efx.h>
 #include <AL/efx-presets.h>
+
+#pragma comment(lib, "OpenAL32.lib")
+
+// for user MP3s
+#include <direct.h>
+#include <shlobj.h>
+#include <shlguid.h>
+#else
+#define _getcwd getcwd
 #endif
 
+#include "common.h"
+#include "crossplatform.h"
+
+#include "sampman.h"
+
 #include "oal/oal_utils.h"
 #include "oal/aldlist.h"
 #include "oal/channel.h"
@@ -38,19 +46,6 @@
 //TODO: max channels
 //TODO: loop count
 
-#ifdef _WIN32
-#pragma comment( lib, "OpenAL32.lib" )
-#endif
-
-// for user MP3s
-#ifdef _WIN32
-#include <direct.h>
-#include <shobjidl.h>
-#include <shlguid.h>
-#else
-#define _getcwd getcwd
-#endif
-
 cSampleManager SampleManager;
 bool _bSampmanInitialised = false;
 
diff --git a/src/collision/TempColModels.cpp b/src/collision/TempColModels.cpp
index dabb6ebb..494c148d 100644
--- a/src/collision/TempColModels.cpp
+++ b/src/collision/TempColModels.cpp
@@ -1,6 +1,7 @@
 #include "common.h"
 
 #include "TempColModels.h"
+#include "Game.h"
 
 CColModel CTempColModels::ms_colModelPed1;
 CColModel CTempColModels::ms_colModelPed2;
diff --git a/src/collision/TempColModels.h b/src/collision/TempColModels.h
index 3e1dd5e1..057728af 100644
--- a/src/collision/TempColModels.h
+++ b/src/collision/TempColModels.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Collision.h"
+#include "ColModel.h"
 
 class CTempColModels
 {
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index 91d2163d..9f6809df 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -126,7 +126,7 @@ CDarkel::DrawMessages()
 #if defined(PS2_HUD) || defined(FIX_BUGS)
 	#ifdef FIX_BUGS
 					CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(34.0f - 1.0f), SCREEN_SCALE_Y(108.0f + 1.0f), gUString);
-	#else                                                  -
+	#else
 					CFont::PrintString(SCREEN_WIDTH-(34.0f - 1.0f), 108.0f + 1.0f, gUString);
 	#endif
 #else
diff --git a/src/control/Garages.h b/src/control/Garages.h
index ee5ac4d3..3a8bc08d 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -1,11 +1,10 @@
 #pragma once
-#include "Automobile.h"
 #include "audio_enums.h"
 #include "Camera.h"
 #include "config.h"
+#include "Lists.h"
 
 class CVehicle;
-class CCamera;
 
 enum eGarageState
 {
diff --git a/src/control/Script.h b/src/control/Script.h
index c0b69e0f..ff1a9706 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -1,7 +1,5 @@
 #pragma once
-#include "common.h"
 #include "Font.h"
-#include "Ped.h"
 #include "PedType.h"
 #include "Text.h"
 #include "Sprite2d.h"
@@ -36,9 +34,11 @@ void FlushLog();
 #define SPHERE_MARKER_PULSE_FRACTION (0.1f)
 
 #ifdef USE_PRECISE_MEASUREMENT_CONVERTION
+#define MILES_IN_METER (0.000621371192f)
 #define METERS_IN_FOOT (0.3048f)
 #define FEET_IN_METER (3.28084f)
 #else
+#define MILES_IN_METER (1 / 1670.f)
 #define METERS_IN_FOOT (0.3f)
 #define FEET_IN_METER (3.33f)
 #endif
diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp
index 27277f0e..6e6e15bf 100644
--- a/src/control/Script3.cpp
+++ b/src/control/Script3.cpp
@@ -32,6 +32,7 @@
 #include "WaterLevel.h"
 #include "Weather.h"
 #include "Zones.h"
+#include "Wanted.h"
 
 int8 CRunningScript::ProcessCommands500To599(int32 command)
 {
diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp
index ecbb337a..40f9f2f1 100644
--- a/src/control/Script4.cpp
+++ b/src/control/Script4.cpp
@@ -38,6 +38,7 @@
 #include "WaterLevel.h"
 #include "World.h"
 #include "Zones.h"
+#include "Wanted.h"
 
 int8 CRunningScript::ProcessCommands800To899(int32 command)
 {
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index bf4893ea..ee3cb959 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -1,11 +1,7 @@
-#if defined RW_D3D9 || defined RWLIBS
-#define DIRECTINPUT_VERSION 0x0800
-#include <dinput.h>
-#endif
-
+#define WITHDINPUT
 #include "common.h"
 #include "platform.h"
-#include "crossplatform.h" // for Windows version
+#include "crossplatform.h"
 #include "ControllerConfig.h"
 #include "Pad.h"
 #include "FileMgr.h"
@@ -2801,7 +2797,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 7bf4be84..65eab125 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -1,10 +1,6 @@
-#if defined RW_D3D9 || defined RWLIBS
-#define DIRECTINPUT_VERSION 0x0800
-#include <dinput.h>
-#endif
-
 #define FORCE_PC_SCALING
 #define WITHWINDOWS
+#define WITHDINPUT
 #include "common.h"
 #ifndef PS2_MENU
 #include "crossplatform.h"
@@ -145,14 +141,6 @@ int8 CMenuManager::m_nDisplayMSAALevel = 0;
 int8 CMenuManager::m_PrefsIslandLoading = ISLAND_LOADING_LOW;
 #endif
 
-#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
-#define MILES_IN_METER 0.000621371192f
-#define FEET_IN_METER 3.28084f
-#else
-#define MILES_IN_METER (1 / 1670.f)
-#define FEET_IN_METER 3.33f
-#endif
-
 int32 CMenuManager::OS_Language = LANG_ENGLISH;
 int8 CMenuManager::m_PrefsUseVibration;
 int8 CMenuManager::m_DisplayControllerOnFoot;
@@ -874,7 +862,11 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
 		m_bWaitingForNewKeyBind = false;
 		m_KeyPressedCode = -1;
 		m_bStartWaitingForKeyBind = false;
+#ifdef LOAD_INI_SETTINGS
+		SaveINIControllerSettings();
+#else
 		SaveSettings();
+#endif
 	}
 
 	if (escPressed) {
@@ -882,7 +874,11 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
 		m_bWaitingForNewKeyBind = false;
 		m_KeyPressedCode = -1;
 		m_bStartWaitingForKeyBind = false;
+#ifdef LOAD_INI_SETTINGS
+		SaveINIControllerSettings();
+#else
 		SaveSettings();
+#endif
 	}
 }
 
@@ -3582,13 +3578,21 @@ CMenuManager::LoadAllTextures()
 	DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
 	DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
 	m_nCurrOption = 0;
+
+#ifdef FIX_BUGS
+	static bool firstTime = true;
+	if (firstTime) {
+		DMAudio.SetRadioInCar(m_PrefsRadioStation);
+		firstTime = false;
+	} else
+#endif
 	m_PrefsRadioStation = DMAudio.GetRadioInCar();
 
 	if (DMAudio.IsMP3RadioChannelAvailable()) {
 		if (m_PrefsRadioStation > USERTRACK)
-			m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
+			m_PrefsRadioStation = CGeneral::GetRandomNumber() % (USERTRACK + 1);
 	} else if (m_PrefsRadioStation > CHATTERBOX)
-		m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
+		m_PrefsRadioStation = CGeneral::GetRandomNumber() % (CHATTERBOX + 1);
 	
 	CFileMgr::SetDir("");
 	//CFileMgr::SetDir("");
@@ -3723,6 +3727,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
+
 	m_PrefsVsync = m_PrefsVsyncDisp;
 	CRenderer::ms_lodDistScale = m_PrefsLOD;
 
@@ -3761,15 +3770,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";
 
 	CFileMgr::SetDirMyDocuments();
@@ -3819,7 +3825,13 @@ CMenuManager::SaveSettings()
 	CFileMgr::CloseFile(fileHandle);
 	CFileMgr::SetDir("");
 
-#ifdef LOAD_INI_SETTINGS
+#else
+	static bool firstTime = true;
+	// In other conditions we already call SaveINIControllerSettings explicitly.
+	if (firstTime) {
+		SaveINIControllerSettings();
+		firstTime = false;
+	}
 	SaveINISettings();
 #endif
 }
@@ -4129,19 +4141,19 @@ CMenuManager::Process(void)
 				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();
 
@@ -5059,6 +5071,9 @@ CMenuManager::ProcessButtonPresses(void)
 						CVehicle::m_bDisableMouseSteering = true;
 						TheCamera.m_bHeadBob = false;
 						SaveSettings();
+#ifdef LOAD_INI_SETTINGS
+						SaveINIControllerSettings();
+#endif
 					}
 					SetHelperText(2);
 					break;
@@ -5110,7 +5125,8 @@ CMenuManager::ProcessButtonPresses(void)
 
 						*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)
@@ -5344,7 +5360,8 @@ CMenuManager::ProcessButtonPresses(void)
 
 						*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 36647899..b0100fdc 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -494,6 +494,7 @@ struct CCustomScreenLayout {
 struct CCFO
 {
 	int8 *value;
+	const char *saveCat;
 	const char *save;
 };
 
@@ -508,11 +509,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;
@@ -528,8 +530,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;
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 7961b981..4fd30b53 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -1,6 +1,3 @@
-#pragma warning( push )
-#pragma warning( disable : 4005)
-#pragma warning( pop )
 #include "common.h"
 #include "platform.h"
 
@@ -10,7 +7,6 @@
 #include "Accident.h"
 #include "Antennas.h"
 #include "Bridge.h"
-#include "Camera.h"
 #include "CarCtrl.h"
 #include "CarGen.h"
 #include "CdStream.h"
@@ -67,7 +63,6 @@
 #include "Shadows.h"
 #include "Skidmarks.h"
 #include "SpecialFX.h"
-#include "Sprite2d.h"
 #include "Stats.h"
 #include "Streaming.h"
 #include "SurfaceTable.h"
diff --git a/src/core/Lists.h b/src/core/Lists.h
index ecf24740..7572e882 100644
--- a/src/core/Lists.h
+++ b/src/core/Lists.h
@@ -1,7 +1,5 @@
 #pragma once
 
-#include "common.h"
-
 class CPtrNode
 {
 public:
diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp
index 4303e4b6..07223608 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) },
+	#define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, "VideoMode", "Windowed", screenModes, 2, true, ScreenModeAfterChange, true) },
 #else
 	#define VIDEOMODE_SELECTOR
 #endif
 
 #ifdef MULTISAMPLING
-	#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) },
+	#define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "Graphics", "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) },
 #else
 	#define MULTISAMPLING_SELECTOR
 #endif
 
 #ifdef CUTSCENE_BORDERS_SWITCH
-	#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false) },
+	#define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&CMenuManager::m_PrefsCutsceneBorders, "Display", "CutsceneBorders", off_on, 2, false) },
 #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) },
+	#define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "Display", "FreeCam", off_on, 2, false) },
 #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) },
+	#define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "Graphics", "PS2AlphaTest", off_on, 2, false) },
 #else
 	#define DUALPASS_SELECTOR 
 #endif
 
 #ifdef NO_ISLAND_LOADING
-	#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
+	#define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "Graphics", "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
 #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) }, \
-		MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false) },
+		MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "Graphics", "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false) }, \
+		MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "Graphics", "MotionBlur", off_on, 2, false) },
 #else
 	#define POSTFX_SELECTORS
 #endif	
 
 #ifdef INVERT_LOOK_FOR_PAD
-	#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "InvertPad", off_on, 2, false) },
+	#define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "Controller", "InvertPad", off_on, 2, false) },
 #else
 	#define INVERT_PAD_SELECTOR
 #endif
@@ -405,7 +405,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
 		CUTSCENE_BORDERS_TOGGLE
 		FREE_CAM_TOGGLE
 		MENUACTION_SUBTITLES,	"FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
-		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefDisplay) },
+		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefDisplay) },
 		MENUACTION_CHANGEMENU,	"FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
 	},
 #endif
@@ -418,9 +418,9 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
 		MENUACTION_LANG_ITA,	"FEL_ITA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
 		MENUACTION_LANG_SPA,    "FEL_SPA", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
 #ifdef MORE_LANGUAGES
-		MENUACTION_CFO_DYNAMIC,    "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) },
-		MENUACTION_CFO_DYNAMIC,    "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) },
-		MENUACTION_CFO_DYNAMIC,    "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) },
+		MENUACTION_CFO_DYNAMIC,    "FEL_POL", { new CCFODynamic(nil, nil, nil, nil, LangPolSelect) },
+		MENUACTION_CFO_DYNAMIC,    "FEL_RUS", { new CCFODynamic(nil, nil, nil, nil, LangRusSelect) },
+		MENUACTION_CFO_DYNAMIC,    "FEL_JAP", { new CCFODynamic(nil, nil, nil, nil, LangJapSelect) },
 #endif
 		MENUACTION_CHANGEMENU,	"FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
 	},
@@ -828,7 +828,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
 		MENUACTION_TRAILS,		"FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
 #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) },
+		MENUACTION_CFO_DYNAMIC,	"FET_DEF", { new CCFODynamic(nil, nil, nil, nil, RestoreDefGraphics) },
 		MENUACTION_CHANGEMENU,	"FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
 	},
 #endif
@@ -839,7 +839,7 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
 		new CCustomScreenLayout({MENUSPRITE_MAINMENU, 40, 60, 20, FONT_BANK, FESCREEN_LEFT_ALIGN, false, MEDIUMTEXT_X_SCALE, MEDIUMTEXT_Y_SCALE}), nil,
 
 		MENUACTION_LABEL,	"FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
-		MENUACTION_CFO_DYNAMIC,	"FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) },
+		MENUACTION_CFO_DYNAMIC,	"FEC_JDE", { new CCFODynamic(nil, nil, nil, DetectJoystickDraw, nil) },
 		MENUACTION_CHANGEMENU,	"FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
 	},
 #endif
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 7187efac..5e5f1326 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -1,11 +1,4 @@
-#pragma warning( push )
-#pragma warning( disable : 4005)
-#if defined RW_D3D9 || defined RWLIBS
-#define DIRECTINPUT_VERSION 0x0800
-#include <dinput.h>
-#endif
-#pragma warning( pop )
-
+#define WITHDINPUT
 #include "common.h"
 #include "crossplatform.h"
 #include "platform.h"
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index 49424b8b..956756e4 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Collision.h"
+#include "ColModel.h"
 
 enum eWastedBustedState
 {
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 67992035..6ecc294a 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -4,7 +4,6 @@
 #include "CopPed.h"
 #include "CutsceneMgr.h"
 #include "DMAudio.h"
-#include "Entity.h"
 #include "EventList.h"
 #include "Explosion.h"
 #include "Fire.h"
@@ -12,10 +11,7 @@
 #include "Glass.h"
 #include "Messages.h"
 #include "ModelIndices.h"
-#include "Object.h"
 #include "ParticleObject.h"
-#include "Ped.h"
-#include "PlayerPed.h"
 #include "Population.h"
 #include "ProjectileInfo.h"
 #include "Record.h"
@@ -24,7 +20,6 @@
 #include "RpAnimBlend.h"
 #include "Shadows.h"
 #include "TempColModels.h"
-#include "Vehicle.h"
 #include "WaterLevel.h"
 #include "World.h"
 
diff --git a/src/core/World.h b/src/core/World.h
index 9d62e79b..3d553752 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -3,6 +3,7 @@
 #include "Game.h"
 #include "Lists.h"
 #include "PlayerInfo.h"
+#include "Collision.h"
 
 /* Sectors span from -2000 to 2000 in x and y.
  * With 100x100 sectors, each is 40x40 units. */
@@ -48,11 +49,6 @@ public:
 
 VALIDATE_SIZE(CSector, 0x28);
 
-class CEntity;
-struct CColPoint;
-struct CColLine;
-struct CStoredCollPoly;
-
 class CWorld
 {
 	static CPtrList ms_bigBuildingsList[NUM_LEVELS];
diff --git a/src/core/Zones.h b/src/core/Zones.h
index 6549dad5..aa0466e8 100644
--- a/src/core/Zones.h
+++ b/src/core/Zones.h
@@ -105,8 +105,8 @@ public:
 	static void SetPedGroup(uint16 zoneid, uint8 day, uint16 pedgroup);
 	static int16 FindAudioZone(CVector *pos);
 	static eLevelName FindZoneForPoint(const CVector &pos);
-	static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &ZoneArray[i]; }
-	static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
+	static CZone *GetPointerForZoneIndex(ssize_t i) { return i == -1 ? nil : &ZoneArray[i]; }
+	static ssize_t GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
 	static void AddZoneToAudioZoneArray(CZone *zone);
 	static void InitialiseAudioZoneArray(void);
 	static void SaveAllZones(uint8 *buffer, uint32 *length);
diff --git a/src/core/common.h b/src/core/common.h
index 9253a465..d7facfd1 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -11,17 +11,34 @@
 #include <string.h>
 #include <math.h>
 
-#if defined _WIN32 && defined WITHWINDOWS 
+#if !defined RW_D3D9 && defined LIBRW
+#undef WITHD3D
+#undef WITHDINPUT
+#endif
+
+#if (defined WITHD3D && !defined LIBRW)
+#define WITHWINDOWS
+#endif
+
+#if defined _WIN32 && defined WITHWINDOWS && !defined _INC_WINDOWS
 #include <windows.h>
 #endif
 
-#if defined _WIN32 && defined WITHD3D
-#include <windows.h>
-#ifndef USE_D3D9
-#include <d3d8types.h>
-#else
-#include <d3d9types.h>
+#ifdef WITHD3D
+	#ifdef LIBRW
+		#define WITH_D3D // librw includes d3d9 itself via this right now
+	#else
+		#ifndef USE_D3D9
+		#include <d3d8.h>
+		#else
+		#include <d3d9.h>
+		#endif
+	#endif
 #endif
+
+#ifdef WITHDINPUT
+#define DIRECTINPUT_VERSION 0x0800
+#include <dinput.h>
 #endif
 
 #include <rwcore.h>
@@ -52,14 +69,6 @@
 
 #define rwVENDORID_ROCKSTAR 0x0253F2
 
-// Get rid of bullshit windows definitions, we're not running on an 8086
-#ifdef far
-#undef far
-#endif
-#ifdef near
-#undef near
-#endif
-
 #define Max(a,b) ((a) > (b) ? (a) : (b))
 #define Min(a,b) ((a) < (b) ? (a) : (b))
 
@@ -79,6 +88,10 @@ typedef int64_t int64;
 // hardcode ucs-2
 typedef uint16_t wchar;
 
+typedef uint8 bool8;
+typedef uint16 bool16;
+typedef uint32 bool32;
+
 #if defined(_MSC_VER)
 typedef ptrdiff_t ssize_t;
 #endif
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 6117462a..09eafe74 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -1,7 +1,6 @@
 #include <csignal>
 #define WITHWINDOWS
 #include "common.h"
-#include "crossplatform.h"
 #include "Renderer.h"
 #include "Credits.h"
 #include "Camera.h"
@@ -31,9 +30,12 @@
 #include "custompipes.h"
 #include "MemoryHeap.h"
 #include "FileMgr.h"
+#include "Camera.h"
+#include "MBlur.h"
+#include "ControllerConfig.h"
 
 #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
-#include "ControllerConfig.h"
+#include "crossplatform.h"
 #endif
 
 #ifndef _WIN32
@@ -88,16 +90,16 @@ CustomFrontendOptionsPopulate(void)
 	if (fd) {
 #ifdef GRAPHICS_MENU_OPTIONS
 		FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
-		FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
-		FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
-		FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
-		FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
+		FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
+		FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
+		FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
+		FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
 #else
 		FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false);
-		FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
-		FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
-		FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
-		FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
+		FrontendOptionAddSelect("FED_VPL", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "Graphics", "VehiclePipeline");
+		FrontendOptionAddSelect("FED_PRM", off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "Graphics", "NeoRimLight");
+		FrontendOptionAddSelect("FED_WLM", off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "Graphics", "NeoLightMaps");
+		FrontendOptionAddSelect("FED_RGL", off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "Graphics", "NeoRoadGloss");
 #endif
 		CFileMgr::CloseFile(fd);
 	}
@@ -110,53 +112,293 @@ 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",
+#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" };
+
+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("re3.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", "VerticalMouseSens", &TheCamera.m_fMouseAccelVertical);
+	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", "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", "VSync", &FrontEndMenuManager.m_PrefsVsyncDisp);
+	ReadIniIfExists("Graphics", "FrameLimiter", &FrontEndMenuManager.m_PrefsFrameLimiter);
+	ReadIniIfExists("Graphics", "Trails", &CMBlur::BlurOn);
+	ReadIniIfExists("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256);
+	ReadIniIfExists("Controller", "Method", &FrontEndMenuManager.m_ControlMethod);
+	ReadIniIfExists("General", "Language", &FrontEndMenuManager.m_PrefsLanguage);
+
+#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++) {
@@ -179,6 +421,7 @@ void LoadINISettings()
 					CFileMgr::CloseFile(gta3set);
 				}
 				CFileMgr::SetDir("");
+				// We call LoadINIControllerSettings after this func., so calling here isn't needed
 				break;
 			}
 		}
@@ -186,6 +429,7 @@ void LoadINISettings()
 #endif
 
 #ifdef CUSTOM_FRONTEND_OPTIONS
+	bool migrate = cfg.category_size("FrontendOptions") != 0;
 	for (int i = 0; i < MENUPAGES; i++) {
 		for (int j = 0; j < NUM_MENUROWS; j++) {
 			CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
@@ -195,7 +439,13 @@ 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);
+
+				// Migrate from old .ini to new .ini
+				if (migrate && ReadIniIfExists("FrontendOptions", option.m_CFO->save, option.m_CFO->value))
+					cfg.remove("FrontendOptions", option.m_CFO->save);
+				else
+					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;
 				}
@@ -203,38 +453,64 @@ 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
-
-#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", "VerticalMouseSens", TheCamera.m_fMouseAccelVertical);
+	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", "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);
+	StoreIni("Graphics", "VSync", FrontEndMenuManager.m_PrefsVsyncDisp);
+	StoreIni("Graphics", "FrameLimiter", FrontEndMenuManager.m_PrefsFrameLimiter);
+	StoreIni("Graphics", "Trails", CMBlur::BlurOn);
+	StoreIni("General", "SkinFile", FrontEndMenuManager.m_PrefsSkinFile, 256);
+	StoreIni("Controller", "Method", FrontEndMenuManager.m_ControlMethod);
+	StoreIni("General", "Language", FrontEndMenuManager.m_PrefsLanguage);
+
+#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
+
+#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++) {
@@ -245,35 +521,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
-
-#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("re3.ini");
+	cfg.write_file("re3.ini");
 }
 
 #endif
diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp
index e6dff12a..092b3e23 100644
--- a/src/extras/custompipes.cpp
+++ b/src/extras/custompipes.cpp
@@ -1,4 +1,4 @@
-#define WITH_D3D
+#define WITHD3D
 #include "common.h"
 
 #ifdef EXTENDED_PIPELINES
diff --git a/src/extras/custompipes.h b/src/extras/custompipes.h
index 183b85da..7ad239f0 100644
--- a/src/extras/custompipes.h
+++ b/src/extras/custompipes.h
@@ -1,7 +1,7 @@
 #pragma once
 
-#ifdef EXTENDED_PIPELINES
 #ifdef LIBRW
+#ifdef EXTENDED_PIPELINES
 
 namespace CustomPipes {
 
diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp
index 1f4ee07d..4242c630 100644
--- a/src/extras/custompipes_d3d9.cpp
+++ b/src/extras/custompipes_d3d9.cpp
@@ -1,4 +1,4 @@
-#define WITH_D3D
+#define WITHD3D
 #include "common.h"
 
 #ifdef RW_D3D9
diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp
index a966de97..5d388bfd 100644
--- a/src/extras/frontendoption.cpp
+++ b/src/extras/frontendoption.cpp
@@ -123,7 +123,7 @@ void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMe
 	option.m_TargetMenu = targetMenu;
 }
 
-void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName, bool disableIfGameLoaded)
+void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveCat, const char* saveKey, bool disableIfGameLoaded)
 {	
 	int8 screenOptionOrder = RegisterNewOption();
 
@@ -139,13 +139,14 @@ void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 n
 		option.m_CFOSelect->displayedValue = *var;
 		option.m_CFOSelect->lastSavedValue = *var;
 	}
-	option.m_CFOSelect->save = saveName;
+	option.m_CFOSelect->saveCat = saveCat;
+	option.m_CFOSelect->save = saveKey;
 	option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter;
 	option.m_CFOSelect->changeFunc = changeFunc;
 	option.m_CFOSelect->disableIfGameLoaded = disableIfGameLoaded;
 }
 
-void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName)
+void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat, const char* saveKey)
 {
 	int8 screenOptionOrder = RegisterNewOption();
 
@@ -156,7 +157,8 @@ void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var,
 	option.m_CFODynamic->drawFunc = drawFunc;
 	option.m_CFODynamic->buttonPressFunc = buttonPressFunc;
 	option.m_CFODynamic->value = var;
-	option.m_CFODynamic->save = saveName;
+	option.m_CFODynamic->saveCat = saveCat;
+	option.m_CFODynamic->save = saveKey;
 }
 
 uint8 FrontendScreenAdd(const char* gxtKey, eMenuSprites sprite, int prevPage, int columnWidth, int headerHeight, int lineHeight,
diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h
index dbd1a300..8b64335a 100644
--- a/src/extras/frontendoption.h
+++ b/src/extras/frontendoption.h
@@ -82,10 +82,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 and saveCat saveKey param. obv), otherwise pass nil/0
 void FrontendOptionAddBuiltinAction(const char* gxtKey, int action, int targetMenu = MENUPAGE_NONE, int saveSlot = SAVESLOT_NONE);
-void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName = nil, bool disableIfGameLoaded = false);
-void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = nil);
+void FrontendOptionAddSelect(const char* gxtKey, 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, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveCat = nil, const char* saveKey = nil);
 
 uint8 FrontendScreenAdd(const char* gxtKey, eMenuSprites sprite, int prevPage, int columnWidth, int headerHeight, int lineHeight, int8 font, float fontScaleX, float fontScaleY, int8 alignment, bool showLeftRightHelper, ReturnPrevPageFunc returnPrevPageFunc = nil);
 #endif
diff --git a/src/extras/ini_parser.hpp b/src/extras/ini_parser.hpp
index 8e88bc29..7bea024c 100644
--- a/src/extras/ini_parser.hpp
+++ b/src/extras/ini_parser.hpp
@@ -158,6 +158,25 @@ namespace linb
 
             /* Too lazy to continue this container... If you need more methods, just add it */
             
+            // re3
+            void remove(const string_type& sect, const key_type& key)
+            {
+                auto it = this->find(sect);
+                if(it != this->end())
+                {
+                    it->second.erase(key);
+                }
+            }
+
+            int category_size(const string_type& sect)
+            {
+                auto it = this->find(sect);
+                if(it != this->end())
+                {
+                    return it->second.size();
+                }
+                return 0;
+            }
 
 #if 1
             bool read_file(const char_type* filename)
diff --git a/src/extras/postfx.cpp b/src/extras/postfx.cpp
index d3b8b8ac..51b91060 100644
--- a/src/extras/postfx.cpp
+++ b/src/extras/postfx.cpp
@@ -1,5 +1,4 @@
-#define WITHWINDOWS
-#define WITH_D3D
+#define WITHD3D
 #include "common.h"
 
 #ifdef EXTENDED_COLOURFILTER
diff --git a/src/extras/screendroplets.cpp b/src/extras/screendroplets.cpp
index ac3a17b2..74c44da0 100644
--- a/src/extras/screendroplets.cpp
+++ b/src/extras/screendroplets.cpp
@@ -1,4 +1,4 @@
-#define WITH_D3D
+#define WITHD3D
 #include "common.h"
 
 #ifdef SCREEN_DROPLETS
diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp
index 6585032b..c1150931 100644
--- a/src/fakerw/fake.cpp
+++ b/src/fakerw/fake.cpp
@@ -1,5 +1,5 @@
 #define _CRT_SECURE_NO_WARNINGS
-#define WITH_D3D
+#define WITH_D3D // not WITHD3D, so it's librw define
 #include <rwcore.h>
 #include <rpworld.h>
 #include <rpmatfx.h>
diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp
index a2779107..f1c7d050 100644
--- a/src/modelinfo/BaseModelInfo.cpp
+++ b/src/modelinfo/BaseModelInfo.cpp
@@ -4,7 +4,7 @@
 #include "TxdStore.h"
 #include "2dEffect.h"
 #include "BaseModelInfo.h"
-
+#include "ColModel.h"
 
 CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
 {
diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h
index 31c7f566..f46cea84 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "Collision.h"
+struct CColModel;
 
 #define MAX_MODEL_NAME (24)
 
diff --git a/src/modelinfo/ModelInfo.h b/src/modelinfo/ModelInfo.h
index 65cfa4e7..4fe1ebb0 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -10,6 +10,7 @@
 #include "VehicleModelInfo.h"
 #include "XtraCompsModelInfo.h"
 #include "Instance.h"
+#include "Game.h"
 
 class CModelInfo
 {
diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h
index f467fe8a..26ab3c3f 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "ClumpModelInfo.h"
+#include "ColModel.h"
 #include "PedType.h"
 
 enum PedNode {
diff --git a/src/peds/Ped.cpp b/src/peds/Ped.cpp
index 269aa084..a9529d2d 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -31,6 +31,7 @@
 #include "ParticleObject.h"
 #include "Floater.h"
 #include "Range2D.h"
+#include "Wanted.h"
 
 CPed *gapTempPedList[50];
 uint16 gnNumTempPedList;
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index c2641a0f..0617a7bb 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -9,6 +9,7 @@
 #include "Physical.h"
 #include "Weapon.h"
 #include "WeaponInfo.h"
+#include "Collision.h"
 
 #define FEET_OFFSET	1.04f
 #define CHECK_NEARBY_THINGS_MAX_DIST	15.0f
diff --git a/src/render/Font.cpp b/src/render/Font.cpp
index 8c183641..7eed0933 100644
--- a/src/render/Font.cpp
+++ b/src/render/Font.cpp
@@ -34,7 +34,7 @@ UnicodeStrlen(const wchar *str)
 }
 
 CFontDetails CFont::Details;
-int16 CFont::NewLine;
+bool16 CFont::NewLine;
 CSprite2d CFont::Sprite[MAX_FONTS];
 
 #ifdef MORE_LANGUAGES
@@ -454,7 +454,7 @@ CFont::InitPerFrame(void)
 		CSprite2d::GetBank(15, Sprite[3].m_pTexture);
 #endif
 	SetDropShadowPosition(0);
-	NewLine = 0;
+	NewLine = false;
 #ifdef BUTTON_ICONS
 	PS2Symbol = BUTTON_NONE;
 #endif
@@ -1048,7 +1048,6 @@ CFont::PrintString(float x, float y, wchar *start, wchar *end, float spwidth)
 }
 #endif
 
-#ifdef XBOX_SUBTITLES
 void
 CFont::PrintStringFromBottom(float x, float y, wchar *str)
 {
@@ -1061,6 +1060,7 @@ CFont::PrintStringFromBottom(float x, float y, wchar *str)
 	PrintString(x, y, str);
 }
 
+#ifdef XBOX_SUBTITLES
 void
 CFont::PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor)
 {
@@ -1263,7 +1263,6 @@ CFont::GetStringWidth(wchar *s, bool spaces)
 	return w;
 }
 
-
 #ifdef MORE_LANGUAGES
 float
 CFont::GetStringWidth_Jap(wchar* s)
@@ -1384,7 +1383,7 @@ CFont::ParseToken(wchar *s, wchar*)
 		switch(*s){
 		case 'N':
 		case 'n':
-			NewLine = 1;
+			NewLine = true;
 			break;
 		case 'b': SetColor(CRGBA(128, 167, 243, 255)); break;
 		case 'g': SetColor(CRGBA(95, 160, 106, 255)); break;
@@ -1430,14 +1429,6 @@ CFont::DrawFonts(void)
 #endif
 }
 
-wchar
-CFont::character_code(uint8 c)
-{
-	if(c < 128)
-		return c;
-	return foreign_table[c-128];
-}
-
 
 void
 CFont::SetScale(float x, float y)
@@ -1453,9 +1444,16 @@ CFont::SetScale(float x, float y)
 }
 
 void
-CFont::SetBackgroundColor(CRGBA col)
+CFont::SetSlantRefPoint(float x, float y)
 {
-	Details.backgroundColor = col;
+	Details.slantRefX = x;
+	Details.slantRefY = y;
+}
+
+void
+CFont::SetSlant(float s)
+{
+	Details.slant = s;
 }
 
 void
@@ -1466,6 +1464,123 @@ CFont::SetColor(CRGBA col)
 		Details.color.a *= Details.alphaFade / 255.0f;
 }
 
+void
+CFont::SetJustifyOn(void)
+{
+	Details.justify = true;
+	Details.centre = false;
+	Details.rightJustify = false;
+}
+
+void
+CFont::SetJustifyOff(void)
+{
+	Details.justify = false;
+	Details.rightJustify = false;
+}
+
+void
+CFont::SetCentreOn(void)
+{
+	Details.centre = true;
+	Details.justify = false;
+	Details.rightJustify = false;
+}
+
+void
+CFont::SetCentreOff(void)
+{
+	Details.centre = false;
+}
+
+void
+CFont::SetWrapx(float x)
+{
+	Details.wrapX = x;
+}
+
+void
+CFont::SetCentreSize(float s)
+{
+	Details.centreSize = s;
+}
+
+void
+CFont::SetBackgroundOn(void)
+{
+	Details.background = true;
+}
+
+void
+CFont::SetBackgroundOff(void)
+{
+	Details.background = false;
+}
+
+void
+CFont::SetBackgroundColor(CRGBA col)
+{
+	Details.backgroundColor = col;
+}
+
+void
+CFont::SetBackGroundOnlyTextOn(void)
+{
+	Details.backgroundOnlyText = true;
+}
+
+void
+CFont::SetBackGroundOnlyTextOff(void)
+{
+	Details.backgroundOnlyText = false;
+}
+
+void
+CFont::SetRightJustifyOn(void)
+{
+	Details.rightJustify = true;
+	Details.justify = false;
+	Details.centre = false;
+}
+
+void
+CFont::SetRightJustifyOff(void)
+{
+	Details.rightJustify = false;
+	Details.justify = false;
+	Details.centre = false;
+}
+
+void
+CFont::SetPropOn(void)
+{
+	Details.proportional = true;
+}
+
+void
+CFont::SetPropOff(void)
+{
+	Details.proportional = false;
+}
+
+void
+CFont::SetFontStyle(int16 style)
+{
+	Details.style = style;
+}
+
+void
+CFont::SetRightJustifyWrap(float wrap)
+{
+	Details.rightJustifyWrap = wrap;
+}
+
+void
+CFont::SetAlphaFade(float fade)
+{
+	Details.alphaFade = fade;
+}
+
 void
 CFont::SetDropColor(CRGBA col)
 {
@@ -1473,3 +1588,17 @@ CFont::SetDropColor(CRGBA col)
 	if (Details.alphaFade < 255.0f)
 		Details.dropColor.a *= Details.alphaFade / 255.0f;
 }
+
+void
+CFont::SetDropShadowPosition(int16 pos)
+{
+	Details.dropShadowPosition = pos;
+}
+
+wchar
+CFont::character_code(uint8 c)
+{
+	if(c < 128)
+		return c;
+	return foreign_table[c-128];
+}
\ No newline at end of file
diff --git a/src/render/Font.h b/src/render/Font.h
index bd7e98bb..a7a4b487 100644
--- a/src/render/Font.h
+++ b/src/render/Font.h
@@ -13,12 +13,12 @@ struct CFontDetails
 	float slant;
 	float slantRefX;
 	float slantRefY;
-	bool justify;
-	bool centre;
-	bool rightJustify;
-	bool background;
-	bool backgroundOnlyText;
-	bool proportional;
+	bool8 justify;
+	bool8 centre;
+	bool8 rightJustify;
+	bool8 background;
+	bool8 backgroundOnlyText;
+	bool8 proportional;
 	float alphaFade;
 	CRGBA backgroundColor;
 	float wrapX;
@@ -97,7 +97,7 @@ class CFont
 #else
 	static int16 Size[MAX_FONTS][193];
 #endif
-	static int16 NewLine;
+	static bool16 NewLine;
 public:
 	static CSprite2d Sprite[MAX_FONTS];
 	static CFontDetails Details;
@@ -116,8 +116,8 @@ public:
 	static void InitPerFrame(void);
 	static void PrintChar(float x, float y, wchar c);
 	static void PrintString(float x, float y, wchar *s);
-#ifdef XBOX_SUBTITLES
 	static void PrintStringFromBottom(float x, float y, wchar *str);
+#ifdef XBOX_SUBTITLES
 	static void PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor);
 #endif
 	static int GetNumberLines(float xstart, float ystart, wchar *s);
@@ -142,49 +142,27 @@ public:
 	static void DrawFonts(void);
 	static uint16 character_code(uint8 c);
 
-	static CFontDetails GetDetails() { return Details; }
 	static void SetScale(float x, float y);
-	static void SetSlantRefPoint(float x, float y) { Details.slantRefX = x; Details.slantRefY = y; }
-	static void SetSlant(float s) { Details.slant = s; }
-	static void SetJustifyOn(void) {
-		Details.justify = true;
-		Details.centre = false;
-		Details.rightJustify = false;
-	}
-	static void SetJustifyOff(void) {
-		Details.justify = false;
-		Details.rightJustify = false;
-	}
-	static void SetRightJustifyOn(void) {
-		Details.rightJustify = true;
-		Details.justify = false;
-		Details.centre = false;
-	}
-	static void SetRightJustifyOff(void) {
-		Details.rightJustify = false;
-		Details.justify = false;
-		Details.centre = false;
-	}
-	static void SetCentreOn(void) {
-		Details.centre = true;
-		Details.justify = false;
-		Details.rightJustify = false;
-	}
-	static void SetCentreOff(void) {
-		Details.centre = false;
-	}
-	static void SetWrapx(float x) { Details.wrapX = x; }
-	static void SetCentreSize(float s) { Details.centreSize = s; }
-	static void SetBackgroundOn(void) { Details.background = true; }
-	static void SetBackgroundOff(void) { Details.background = false; }
-	static void SetBackGroundOnlyTextOn(void) { Details.backgroundOnlyText = true; }
-	static void SetBackGroundOnlyTextOff(void) { Details.backgroundOnlyText = false; }
-	static void SetPropOn(void) { Details.proportional = true; }
-	static void SetPropOff(void) { Details.proportional = false; }
-	static void SetFontStyle(int16 style) { Details.style = style; }
-	static void SetRightJustifyWrap(float wrap) { Details.rightJustifyWrap = wrap; }
-	static void SetAlphaFade(float fade) { Details.alphaFade = fade; }
-	static void SetDropShadowPosition(int16 pos) { Details.dropShadowPosition = pos; }
+	static void SetSlantRefPoint(float x, float y);
+	static void SetSlant(float s);
+	static void SetJustifyOn(void);
+	static void SetJustifyOff(void);
+	static void SetRightJustifyOn(void);
+	static void SetRightJustifyOff(void);
+	static void SetCentreOn(void);
+	static void SetCentreOff(void);
+	static void SetWrapx(float x);
+	static void SetCentreSize(float s);
+	static void SetBackgroundOn(void);
+	static void SetBackgroundOff(void);
+	static void SetBackGroundOnlyTextOn(void);
+	static void SetBackGroundOnlyTextOff(void);
+	static void SetPropOn(void);
+	static void SetPropOff(void);
+	static void SetFontStyle(int16 style);
+	static void SetRightJustifyWrap(float wrap);
+	static void SetAlphaFade(float fade);
+	static void SetDropShadowPosition(int16 pos);
 	static void SetBackgroundColor(CRGBA col);
 	static void SetColor(CRGBA col);
 	static void SetDropColor(CRGBA col);
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index de15358e..a7d07ad9 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -1,4 +1,3 @@
-#define WITHWINDOWS
 #ifndef LIBRW
 #define WITHD3D
 #endif
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index 131e77fe..d41f27e3 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -1,4 +1,4 @@
-#define WITH_D3D
+#define WITHD3D
 #include "common.h"
 
 #include "main.h"
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index d004656c..65e342ed 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -1,6 +1,4 @@
-#if defined RW_D3D9 || defined RWLIBS
 #define WITHD3D
-#endif
 #include "common.h"
 #include <rpskin.h>
 
diff --git a/src/save/MemoryCard.cpp b/src/save/MemoryCard.cpp
index c8ebcd86..d6e95d33 100644
--- a/src/save/MemoryCard.cpp
+++ b/src/save/MemoryCard.cpp
@@ -1,6 +1,7 @@
 #define WITHWINDOWS
 #include "common.h"
 #ifdef PS2_MENU
+#include "crossplatform.h"
 #include "MemoryCard.h"
 #include "main.h"
 #include "DMAudio.h"
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 93bfde5a..5f87d600 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -1,22 +1,30 @@
 #if defined RW_GL3 && !defined LIBRW_SDL2
 
 #ifdef _WIN32
-#include <windows.h>
+#include <shlobj.h>
+#include <basetsd.h>
 #include <mmsystem.h>
+#include <regstr.h>
 #include <shellapi.h>
 #include <windowsx.h>
-#include <basetsd.h>
-#include <regstr.h>
-#include <shlobj.h>
+
+DWORD _dwOperatingSystemVersion;
+#include "resource.h"
+#else
+long _dwOperatingSystemVersion;
+#ifndef __APPLE__
+#include <sys/sysinfo.h>
+#else
+#include <mach/mach_host.h>
+#include <sys/sysctl.h>
+#endif
+#include <errno.h>
+#include <locale.h>
+#include <signal.h>
+#include <stddef.h>
 #endif
 
-#define WITHWINDOWS
 #include "common.h"
-
-#pragma warning( push )
-#pragma warning( disable : 4005)
-#pragma warning( pop )
-
 #if (defined(_MSC_VER))
 #include <tchar.h>
 #endif /* (defined(_MSC_VER)) */
@@ -73,23 +81,6 @@ static psGlobalType PsGlobal;
 size_t _dwMemAvailPhys;
 RwUInt32 gGameState;
 
-#ifdef _WIN32
-DWORD _dwOperatingSystemVersion;
-#include "resource.h"
-#else
-long _dwOperatingSystemVersion;
-#ifndef __APPLE__
-#include <sys/sysinfo.h>
-#else
-#include <mach/mach_host.h>
-#include <sys/sysctl.h>
-#endif
-#include <stddef.h>
-#include <locale.h>
-#include <signal.h>
-#include <errno.h>
-#endif
-
 #ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
 char gSelectedJoystickName[128] = "";
 #endif
@@ -1607,6 +1598,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();
 		
@@ -1619,6 +1611,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 53844319..5a0c7db2 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -2,7 +2,6 @@
 
 #define _WIN32_WINDOWS 0x0500
 #define WINVER 0x0500
-#define DIRECTINPUT_VERSION 0x0800
 
 #include <winerror.h>
 #include <windows.h>
@@ -20,13 +19,7 @@
 #pragma warning( push )
 #pragma warning( disable : 4005)
 
-#ifdef USE_D3D9
-#include <d3d9.h>
-#else
-#include <d3d8.h>
-#endif
 #include <ddraw.h>
-#include <dinput.h>
 #include <DShow.h>
 #pragma warning( pop )
 
@@ -41,6 +34,9 @@
 #pragma comment( lib, "strmiids.lib" )
 #pragma comment( lib, "dinput8.lib" )
 
+#define WITHD3D
+#define WITHDINPUT
+#include "common.h"
 #if (defined(_MSC_VER))
 #include <tchar.h>
 #endif /* (defined(_MSC_VER)) */
@@ -82,7 +78,6 @@ static psGlobalType PsGlobal;
 #define JIF(x) if (FAILED(hr=(x))) \
 	{debug(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return;}
 
-#include "common.h"
 #include "main.h"
 #include "FileMgr.h"
 #include "Text.h"
@@ -93,12 +88,14 @@ static psGlobalType PsGlobal;
 #include "Frontend.h"
 #include "Game.h"
 #include "PCSave.h"
-#include "MemoryCard.h"
-#include "Sprite2d.h"
 #include "AnimViewer.h"
-#include "Font.h"
 #include "MemoryMgr.h"
 
+#ifdef PS2_MENU
+#include "MemoryCard.h"
+#include "Font.h"
+#endif
+	
 VALIDATE_SIZE(psGlobalType, 0x28);
 
 // DirectShow interfaces
@@ -2145,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();
 		
@@ -2157,6 +2155,10 @@ WinMain(HINSTANCE instance,
 		}
 		
 		CFileMgr::SetDir("");
+
+#ifdef LOAD_INI_SETTINGS
+		LoadINIControllerSettings();
+#endif
 	}
 	
 	SetErrorMode(SEM_FAILCRITICALERRORS);
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index ed187849..966042e2 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -44,6 +44,7 @@
 #include "PlayerPed.h"
 #include "Object.h"
 #include "Automobile.h"
+#include "Wanted.h"
 
 bool bAllCarCheat;	// unused
 
@@ -592,7 +593,7 @@ CAutomobile::ProcessControl(void)
 		float fwdSpeed = Abs(DotProduct(m_vecMoveSpeed, GetForward()));
 		CVector contactPoints[4];	// relative to model
 		CVector contactSpeeds[4];	// speed at contact points
-		CVector springDirections[4];	// normalized, in model space
+		CVector springDirections[4];	// normalized, in world space
 
 		for(i = 0; i < 4; i++){
 			// Set spring under certain circumstances
@@ -759,10 +760,10 @@ CAutomobile::ProcessControl(void)
 			CVector wheelRight = Multiply3x3(GetMatrix(), CVector(c, s, 0.0f));
 
 			if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){
-				if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
-					fThrust = 0.0f;
-				else
+				if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
 					fThrust = acceleration;
+				else
+					fThrust = 0.0f;
 
 				m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceA = SURFACE_WHEELBASE;
 				float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_LEFT])*traction;
@@ -793,10 +794,10 @@ CAutomobile::ProcessControl(void)
 			}
 
 			if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
-				if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
-					fThrust = 0.0f;
-				else
+				if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
 					fThrust = acceleration;
+				else
+					fThrust = 0.0f;
 
 				m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceA = SURFACE_WHEELBASE;
 				float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT])*traction;
@@ -830,9 +831,7 @@ CAutomobile::ProcessControl(void)
 		// Process front wheels off ground
 
 		if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
-			if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
-				m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
-			else{
+			if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
 				if(acceleration > 0.0f){
 					if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] < 2.0f)
 						m_aWheelSpeed[CARWHEEL_FRONT_LEFT] -= 0.2f;
@@ -840,13 +839,13 @@ CAutomobile::ProcessControl(void)
 					if(m_aWheelSpeed[CARWHEEL_FRONT_LEFT] > -2.0f)
 						m_aWheelSpeed[CARWHEEL_FRONT_LEFT] += 0.1f;
 				}
+			}else{
+				m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
 			}
 			m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
 		}
 		if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
-			if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
-				m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
-			else{
+			if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
 				if(acceleration > 0.0f){
 					if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] < 2.0f)
 						m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] -= 0.2f;
@@ -854,6 +853,8 @@ CAutomobile::ProcessControl(void)
 					if(m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] > -2.0f)
 						m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] += 0.1f;
 				}
+			}else{
+				m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
 			}
 			m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
 		}
@@ -874,10 +875,10 @@ CAutomobile::ProcessControl(void)
 #endif
 
 			if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f){
-				if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
-					fThrust = 0.0f;
-				else
+				if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
 					fThrust = acceleration;
+				else
+					fThrust = 0.0f;
 
 				m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceA = SURFACE_WHEELBASE;
 				float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_LEFT])*traction;
@@ -908,10 +909,10 @@ CAutomobile::ProcessControl(void)
 			}
 
 			if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
-				if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
-					fThrust = 0.0f;
-				else
+				if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
 					fThrust = acceleration;
+				else
+					fThrust = 0.0f;
 
 				m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceA = SURFACE_WHEELBASE;
 				float adhesion = CSurfaceTable::GetAdhesiveLimit(m_aWheelColPoints[CARWHEEL_REAR_RIGHT])*traction;
@@ -945,9 +946,7 @@ CAutomobile::ProcessControl(void)
 		// Process rear wheels off ground
 
 		if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){
-			if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
-				m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
-			else{
+			if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
 				if(acceleration > 0.0f){
 					if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] < 2.0f)
 						m_aWheelSpeed[CARWHEEL_REAR_LEFT] -= 0.2f;
@@ -955,13 +954,13 @@ CAutomobile::ProcessControl(void)
 					if(m_aWheelSpeed[CARWHEEL_REAR_LEFT] > -2.0f)
 						m_aWheelSpeed[CARWHEEL_REAR_LEFT] += 0.1f;
 				}
+			}else{
+				m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
 			}
 			m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT];
 		}
 		if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){
-			if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
-				m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
-			else{
+			if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) && acceleration != 0.0f){
 				if(acceleration > 0.0f){
 					if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] < 2.0f)
 						m_aWheelSpeed[CARWHEEL_REAR_RIGHT] -= 0.2f;
@@ -969,6 +968,8 @@ CAutomobile::ProcessControl(void)
 					if(m_aWheelSpeed[CARWHEEL_REAR_RIGHT] > -2.0f)
 						m_aWheelSpeed[CARWHEEL_REAR_RIGHT] += 0.1f;
 				}
+			}else{
+				m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
 			}
 			m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT];
 		}
diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h
index 05876201..9848bb74 100644
--- a/src/vehicles/HandlingMgr.h
+++ b/src/vehicles/HandlingMgr.h
@@ -149,8 +149,8 @@ public:
 	void DisplayHandlingData(CVehicle *, tHandlingData *, uint8, bool);
 	int32 GetHandlingId(const char *name);
 	tHandlingData *GetHandlingData(tVehicleType id) { return &HandlingData[id]; }
-	bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'R'; }
-	bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
+	bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'F'; }
+	bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType != 'R'; }
 };
 VALIDATE_SIZE(cHandlingDataMgr, 0x3030);
 extern cHandlingDataMgr mod_HandlingManager;
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index 7066a0ea..a6a4f815 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -3,8 +3,9 @@
 #include "Physical.h"
 #include "AutoPilot.h"
 #include "ModelIndices.h"
-#include "AnimManager.h"
-#include "Weapon.h"
+#include "AnimationId.h"
+#include "WeaponType.h"
+#include "Collision.h"
 
 class CPed;
 class CFire;
diff --git a/vendor/milessdk/include/mss.h b/vendor/milessdk/include/mss.h
index 38371eb9..b5b20bea 100644
--- a/vendor/milessdk/include/mss.h
+++ b/vendor/milessdk/include/mss.h
@@ -56,61 +56,86 @@ typedef struct _AILSOUNDINFO
 	void const *initial_ptr;
 } AILSOUNDINFO;
 
-#define DLLEXPORT extern "C" __declspec(dllexport)
+typedef U32 (WINAPI *AIL_file_open_callback)(char const * Filename, U32 * FileHandle);
 
-DLLEXPORT S32 WINAPI AIL_enumerate_3D_providers(HPROENUM *next, HPROVIDER *dest, C8 **name);
-DLLEXPORT void WINAPI AIL_release_3D_sample_handle(H3DSAMPLE S);
-DLLEXPORT void WINAPI AIL_close_3D_provider(HPROVIDER lib);
-DLLEXPORT void WINAPI AIL_set_3D_provider_preference(HPROVIDER lib, C8 const *name, void const *val);
-DLLEXPORT M3DRESULT WINAPI AIL_open_3D_provider(HPROVIDER lib);
-DLLEXPORT C8 *WINAPI AIL_last_error(void);
-DLLEXPORT S32 WINAPI AIL_3D_room_type(HPROVIDER lib);
-DLLEXPORT void WINAPI AIL_set_3D_room_type(HPROVIDER lib, S32 room_type);
-DLLEXPORT void WINAPI AIL_3D_provider_attribute(HPROVIDER lib, C8 const *name, void *val);
-DLLEXPORT H3DSAMPLE WINAPI AIL_allocate_3D_sample_handle(HPROVIDER lib);
-DLLEXPORT void WINAPI AIL_set_3D_sample_effects_level(H3DSAMPLE S, F32 effects_level);
-DLLEXPORT void WINAPI AIL_set_3D_speaker_type(HPROVIDER lib, S32 speaker_type);
-DLLEXPORT HSTREAM WINAPI AIL_open_stream(HDIGDRIVER dig, C8 const *filename, S32 stream_mem);
-DLLEXPORT void WINAPI AIL_stream_ms_position(HSTREAM S, S32 *total_milliseconds, S32 *current_milliseconds);
-DLLEXPORT void WINAPI AIL_close_stream(HSTREAM stream);
-DLLEXPORT S32 WINAPI AIL_digital_handle_release(HDIGDRIVER drvr);
-DLLEXPORT S32 WINAPI AIL_digital_handle_reacquire(HDIGDRIVER drvr);
-DLLEXPORT C8 *WINAPI AIL_set_redist_directory(C8 const *dir);
-DLLEXPORT S32 WINAPI AIL_startup(void);
-DLLEXPORT S32 WINAPI AIL_set_preference(U32 number, S32 value);
-DLLEXPORT HDIGDRIVER WINAPI AIL_open_digital_driver(U32 frequency, S32 bits, S32 channel, U32 flags);
-DLLEXPORT void *WINAPI AIL_mem_alloc_lock(U32 size);
-DLLEXPORT HSAMPLE WINAPI AIL_allocate_sample_handle(HDIGDRIVER dig);
-DLLEXPORT void WINAPI AIL_init_sample(HSAMPLE S);
-DLLEXPORT void WINAPI AIL_set_sample_type(HSAMPLE S, S32 format, U32 flags);
-DLLEXPORT void WINAPI AIL_pause_stream(HSTREAM stream, S32 onoff);
-DLLEXPORT void WINAPI AIL_release_sample_handle(HSAMPLE S);
-DLLEXPORT void WINAPI AIL_mem_free_lock(void *ptr);
-DLLEXPORT void WINAPI AIL_close_digital_driver(HDIGDRIVER dig);
-DLLEXPORT void WINAPI AIL_shutdown(void);
-DLLEXPORT void WINAPI AIL_set_3D_sample_volume(H3DSAMPLE S, S32 volume);
-DLLEXPORT void WINAPI AIL_set_sample_volume(HSAMPLE S, S32 volume);
-DLLEXPORT void WINAPI AIL_set_sample_address(HSAMPLE S, void const *start, U32 len);
-DLLEXPORT S32 WINAPI AIL_set_3D_sample_info(H3DSAMPLE S, AILSOUNDINFO const *info);
-DLLEXPORT void WINAPI AIL_set_3D_position(H3DPOBJECT obj, F32 X, F32 Y, F32 Z);
-DLLEXPORT void WINAPI AIL_set_3D_sample_distances(H3DSAMPLE S, F32 max_dist, F32 min_dist);
-DLLEXPORT void WINAPI AIL_set_sample_pan(HSAMPLE S, S32 pan);
-DLLEXPORT void WINAPI AIL_set_sample_playback_rate(HSAMPLE S, S32 playback_rate);
-DLLEXPORT void WINAPI AIL_set_3D_sample_playback_rate(H3DSAMPLE S, S32 playback_rate);
-DLLEXPORT void WINAPI AIL_set_sample_loop_block(HSAMPLE S, S32 loop_start_offset, S32 loop_end_offset);
-DLLEXPORT void WINAPI AIL_set_3D_sample_loop_block(H3DSAMPLE S, S32 loop_start_offset, S32 loop_end_offset);
-DLLEXPORT void WINAPI AIL_set_sample_loop_count(HSAMPLE S, S32 loop_count);
-DLLEXPORT void WINAPI AIL_set_3D_sample_loop_count(H3DSAMPLE S, S32 loops);
-DLLEXPORT U32 WINAPI AIL_sample_status(HSAMPLE S);
-DLLEXPORT U32 WINAPI AIL_3D_sample_status(H3DSAMPLE S);
-DLLEXPORT void WINAPI AIL_start_sample(HSAMPLE S);
-DLLEXPORT void WINAPI AIL_start_3D_sample(H3DSAMPLE S);
-DLLEXPORT void WINAPI AIL_end_sample(HSAMPLE S);
-DLLEXPORT void WINAPI AIL_end_3D_sample(H3DSAMPLE S);
-DLLEXPORT void WINAPI AIL_set_stream_loop_count(HSTREAM stream, S32 count);
-DLLEXPORT S32 WINAPI AIL_service_stream(HSTREAM stream, S32 fillup);
-DLLEXPORT void WINAPI AIL_start_stream(HSTREAM stream);
-DLLEXPORT void WINAPI AIL_set_stream_ms_position(HSTREAM S, S32 milliseconds);
-DLLEXPORT void WINAPI AIL_set_stream_volume(HSTREAM stream, S32 volume);
-DLLEXPORT void WINAPI AIL_set_stream_pan(HSTREAM stream, S32 pan);
-DLLEXPORT S32 WINAPI AIL_stream_status(HSTREAM stream);
+typedef void (WINAPI *AIL_file_close_callback)(U32 FileHandle);
+
+#define AIL_FILE_SEEK_BEGIN 0
+#define AIL_FILE_SEEK_CURRENT 1
+#define AIL_FILE_SEEK_END 2
+
+typedef S32(WINAPI *AIL_file_seek_callback)(U32 FileHandle, S32 Offset, U32 Type);
+
+typedef U32(WINAPI *AIL_file_read_callback)(U32 FileHandle, void* Buffer, U32 Bytes);
+
+#ifdef RE3MSS_EXPORTS
+#define RE3MSS_EXPORT __declspec(dllexport)
+#else
+#define RE3MSS_EXPORT __declspec(dllimport)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+RE3MSS_EXPORT S32 WINAPI AIL_enumerate_3D_providers(HPROENUM *next, HPROVIDER *dest, C8 **name);
+RE3MSS_EXPORT void WINAPI AIL_release_3D_sample_handle(H3DSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_close_3D_provider(HPROVIDER lib);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_provider_preference(HPROVIDER lib, C8 const *name, void const *val);
+RE3MSS_EXPORT M3DRESULT WINAPI AIL_open_3D_provider(HPROVIDER lib);
+RE3MSS_EXPORT C8 *WINAPI AIL_last_error(void);
+RE3MSS_EXPORT S32 WINAPI AIL_3D_room_type(HPROVIDER lib);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_room_type(HPROVIDER lib, S32 room_type);
+RE3MSS_EXPORT void WINAPI AIL_3D_provider_attribute(HPROVIDER lib, C8 const *name, void *val);
+RE3MSS_EXPORT H3DSAMPLE WINAPI AIL_allocate_3D_sample_handle(HPROVIDER lib);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_sample_effects_level(H3DSAMPLE S, F32 effects_level);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_speaker_type(HPROVIDER lib, S32 speaker_type);
+RE3MSS_EXPORT HSTREAM WINAPI AIL_open_stream(HDIGDRIVER dig, C8 const *filename, S32 stream_mem);
+RE3MSS_EXPORT void WINAPI AIL_stream_ms_position(HSTREAM S, S32 *total_milliseconds, S32 *current_milliseconds);
+RE3MSS_EXPORT void WINAPI AIL_close_stream(HSTREAM stream);
+RE3MSS_EXPORT S32 WINAPI AIL_digital_handle_release(HDIGDRIVER drvr);
+RE3MSS_EXPORT S32 WINAPI AIL_digital_handle_reacquire(HDIGDRIVER drvr);
+RE3MSS_EXPORT C8 *WINAPI AIL_set_redist_directory(C8 const *dir);
+RE3MSS_EXPORT S32 WINAPI AIL_startup(void);
+RE3MSS_EXPORT S32 WINAPI AIL_set_preference(U32 number, S32 value);
+RE3MSS_EXPORT HDIGDRIVER WINAPI AIL_open_digital_driver(U32 frequency, S32 bits, S32 channel, U32 flags);
+RE3MSS_EXPORT void *WINAPI AIL_mem_alloc_lock(U32 size);
+RE3MSS_EXPORT HSAMPLE WINAPI AIL_allocate_sample_handle(HDIGDRIVER dig);
+RE3MSS_EXPORT void WINAPI AIL_init_sample(HSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_type(HSAMPLE S, S32 format, U32 flags);
+RE3MSS_EXPORT void WINAPI AIL_pause_stream(HSTREAM stream, S32 onoff);
+RE3MSS_EXPORT void WINAPI AIL_release_sample_handle(HSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_mem_free_lock(void *ptr);
+RE3MSS_EXPORT void WINAPI AIL_close_digital_driver(HDIGDRIVER dig);
+RE3MSS_EXPORT void WINAPI AIL_shutdown(void);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_sample_volume(H3DSAMPLE S, S32 volume);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_volume(HSAMPLE S, S32 volume);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_address(HSAMPLE S, void const *start, U32 len);
+RE3MSS_EXPORT S32 WINAPI AIL_set_3D_sample_info(H3DSAMPLE S, AILSOUNDINFO const *info);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_position(H3DPOBJECT obj, F32 X, F32 Y, F32 Z);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_sample_distances(H3DSAMPLE S, F32 max_dist, F32 min_dist);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_pan(HSAMPLE S, S32 pan);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_playback_rate(HSAMPLE S, S32 playback_rate);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_sample_playback_rate(H3DSAMPLE S, S32 playback_rate);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_loop_block(HSAMPLE S, S32 loop_start_offset, S32 loop_end_offset);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_sample_loop_block(H3DSAMPLE S, S32 loop_start_offset, S32 loop_end_offset);
+RE3MSS_EXPORT void WINAPI AIL_set_sample_loop_count(HSAMPLE S, S32 loop_count);
+RE3MSS_EXPORT void WINAPI AIL_set_3D_sample_loop_count(H3DSAMPLE S, S32 loops);
+RE3MSS_EXPORT U32 WINAPI AIL_sample_status(HSAMPLE S);
+RE3MSS_EXPORT U32 WINAPI AIL_3D_sample_status(H3DSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_start_sample(HSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_start_3D_sample(H3DSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_end_sample(HSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_end_3D_sample(H3DSAMPLE S);
+RE3MSS_EXPORT void WINAPI AIL_set_stream_loop_count(HSTREAM stream, S32 count);
+RE3MSS_EXPORT S32 WINAPI AIL_service_stream(HSTREAM stream, S32 fillup);
+RE3MSS_EXPORT void WINAPI AIL_start_stream(HSTREAM stream);
+RE3MSS_EXPORT void WINAPI AIL_set_stream_ms_position(HSTREAM S, S32 milliseconds);
+RE3MSS_EXPORT void WINAPI AIL_set_stream_volume(HSTREAM stream, S32 volume);
+RE3MSS_EXPORT void WINAPI AIL_set_stream_pan(HSTREAM stream, S32 pan);
+RE3MSS_EXPORT S32 WINAPI AIL_stream_status(HSTREAM stream);
+RE3MSS_EXPORT void WINAPI AIL_set_file_callbacks(AIL_file_open_callback opencb, AIL_file_close_callback closecb, AIL_file_seek_callback seekcb, AIL_file_read_callback readcb);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/vendor/milessdk/lib/mss32.lib b/vendor/milessdk/lib/mss32.lib
index f97091c7..e63a1a05 100644
Binary files a/vendor/milessdk/lib/mss32.lib and b/vendor/milessdk/lib/mss32.lib differ