diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index 5519d899..5f94093e 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -83,12 +83,41 @@ cMusicManager::DisplayRadioStationName()
 		if(m_bPlayerInCar && !m_bPreviousPlayerInCar)
 			pCurrentStation = nil;
 
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+		if(gNumRetunePresses < 0) {
+			gStreamedSound = m_nCurrentStreamedSound;
+
+			if(gStreamedSound == STREAMED_SOUND_CITY_AMBIENT ||
+			   gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) {
+				gStreamedSound = RADIO_OFF;
+			} else {
+
+				if(gStreamedSound >
+				   STREAMED_SOUND_RADIO_MP3_PLAYER)
+					return;
+			}
+
+			gRetuneCounter = gNumRetunePresses;
+			pRetune = gStreamedSound;
+
+			while(gRetuneCounter < 0) {
+				if(pRetune == HEAD_RADIO) {
+					pRetune = RADIO_OFF;
+				} else if(pRetune == RADIO_OFF || pRetune == POLICE_RADIO) {
+					pRetune =  SampleManager.IsMP3RadioChannelAvailable() ? USERTRACK : USERTRACK - 1;
+				} else
+					pRetune--;
+
+				++gRetuneCounter;
+			}
+		} else
+#endif
 		if(SampleManager.IsMP3RadioChannelAvailable()) {
 			gStreamedSound = m_nCurrentStreamedSound;
 
 			if(gStreamedSound == STREAMED_SOUND_CITY_AMBIENT ||
 			   gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) {
-				gStreamedSound = STREAMED_SOUND_RADIO_POLICE;
+				gStreamedSound = RADIO_OFF;
 			} else {
 
 				if(gStreamedSound >
@@ -140,10 +169,17 @@ cMusicManager::DisplayRadioStationName()
 		case FLASHBACK: string = TheText.Get("FEA_FM7"); break;
 		case CHATTERBOX: string = TheText.Get("FEA_FM8"); break;
 		case USERTRACK: string = TheText.Get("FEA_FM9"); break;
+#ifdef RADIO_OFF_TEXT
+		case RADIO_OFF: string = TheText.Get("FEM_OFF"); break;
+#endif
 		default: return;
 		};
 
+#ifdef RADIO_OFF_TEXT
+		if(pRetune == USERTRACK && !SampleManager.IsMP3RadioChannelAvailable()) { return; }
+#else
 		if(pRetune > CHATTERBOX && !SampleManager.IsMP3RadioChannelAvailable()) { return; }
+#endif
 
 		if(string && pCurrentStation != string ||
 		   m_nCurrentStreamedSound == STREAMED_SOUND_RADIO_MP3_PLAYER &&
@@ -442,17 +478,31 @@ cMusicManager::ServiceGameMode()
 	if (m_bPlayerInCar) {
 		if (FindPlayerPed() != nil
 			&& !FindPlayerPed()->DyingOrDead()
-			&& CPad::GetPad(0)->ChangeStationJustDown()
 			&& !CReplay::IsPlayingBack()
 			&& FindPlayerVehicle() != nil
 			&& !UsesPoliceRadio(FindPlayerVehicle())) {
-				gRetuneCounter = 30;
-				gNumRetunePresses++;
-				AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
-				if (SampleManager.IsMP3RadioChannelAvailable()) {
-					if (gNumRetunePresses > RADIO_OFF)
-						gNumRetunePresses -= RADIO_OFF;
+
+				if (CPad::GetPad(0)->ChangeStationJustDown()) {
+					gRetuneCounter = 30;
+					gNumRetunePresses++;
+					AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
+					if (SampleManager.IsMP3RadioChannelAvailable()) {
+						if (gNumRetunePresses > RADIO_OFF)
+							gNumRetunePresses -= RADIO_OFF;
+					}
 				}
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+				else if(CPad::GetPad(0)->GetMouseWheelDownJustDown() || CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
+					int scrollNext = ControlsManager.GetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, MOUSE);
+					int scrollPrev = scrollNext == rsMOUSEWHEELUPBUTTON ? rsMOUSEWHEELDOWNBUTTON : scrollNext == rsMOUSEWHEELDOWNBUTTON ? rsMOUSEWHEELUPBUTTON : -1;
+
+					if (scrollPrev != -1 && !ControlsManager.IsAnyVehicleActionAssignedToMouseKey(scrollPrev)) {
+						gRetuneCounter = 30;
+						gNumRetunePresses--;
+						AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
+					}
+				}
+#endif
 		}
 	} else {
 		nFramesSinceCutsceneEnded = -1;
@@ -494,10 +544,22 @@ cMusicManager::ServiceGameMode()
 			gNumRetunePresses = 0;
 			m_bSetNextStation = false;
 		}
+		// Because when you switch radio back and forth, gNumRetunePresses will be 0 but gRetuneCounter won't.
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+		if (gRetuneCounter != 0) {
+			if (gRetuneCounter > 1) gRetuneCounter--;
+			else if (gRetuneCounter == 1) gRetuneCounter = -1;
+			else if (gRetuneCounter == -1) {
+				m_bSetNextStation = true;
+				gRetuneCounter = 0;
+			}
+		}
+#else
 		if (gNumRetunePresses) {
 			if (gRetuneCounter != 0) gRetuneCounter--;
 			else m_bSetNextStation = true;
 		}
+#endif
 		if (gRetuneCounter)
 			AudioManager.DoPoliceRadioCrackle();
 		if (m_bSetNextStation) {
@@ -863,6 +925,20 @@ cMusicManager::GetNextCarTuning()
 	if (veh == nil) return RADIO_OFF;
 	if (UsesPoliceRadio(veh)) return POLICE_RADIO;
 	if (gNumRetunePresses != 0) {
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+		if (gNumRetunePresses < 0) {
+			while (gNumRetunePresses < 0) {
+				if(veh->m_nRadioStation == HEAD_RADIO) {
+					veh->m_nRadioStation = RADIO_OFF;
+				} else if(veh->m_nRadioStation == RADIO_OFF || veh->m_nRadioStation == POLICE_RADIO) {
+					veh->m_nRadioStation = SampleManager.IsMP3RadioChannelAvailable() ? USERTRACK : USERTRACK - 1;
+				} else
+					veh->m_nRadioStation--;
+
+				++gNumRetunePresses;
+			}
+		} else
+#endif
 		if (SampleManager.IsMP3RadioChannelAvailable()) {
 			if (veh->m_nRadioStation == RADIO_OFF)
 				veh->m_nRadioStation = POLICE_RADIO;
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index cadba7f2..b56a19f0 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -1718,6 +1718,52 @@ void CControllerConfigManager::DeleteMatching1rstPersonControls(e_ControllerActi
 
 #undef CLEAR_ACTION_IF_NEEDED
 
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+#define CHECK_ACTION(action) \
+if (key == GetControllerKeyAssociatedWithAction(action, type))\
+	return true;
+
+bool CControllerConfigManager::IsAnyVehicleActionAssignedToMouseKey(int32 key)
+{
+	const eControllerType type = MOUSE;
+	if (!GetIsKeyBlank(key, type))
+	{
+#ifdef BIND_VEHICLE_FIREWEAPON
+		CHECK_ACTION(VEHICLE_FIREWEAPON);
+#endif
+		CHECK_ACTION(VEHICLE_LOOKBEHIND);
+		CHECK_ACTION(VEHICLE_LOOKLEFT);
+		CHECK_ACTION(VEHICLE_LOOKRIGHT);
+		CHECK_ACTION(VEHICLE_LOOKBEHIND); // note: duplicate
+		CHECK_ACTION(VEHICLE_HORN);
+		CHECK_ACTION(VEHICLE_HANDBRAKE);
+		CHECK_ACTION(VEHICLE_ACCELERATE);
+		CHECK_ACTION(VEHICLE_BRAKE);
+		CHECK_ACTION(VEHICLE_CHANGE_RADIO_STATION);
+		CHECK_ACTION(TOGGLE_SUBMISSIONS);
+		CHECK_ACTION(VEHICLE_TURRETLEFT);
+		CHECK_ACTION(VEHICLE_TURRETRIGHT);
+		CHECK_ACTION(VEHICLE_TURRETUP);
+		CHECK_ACTION(VEHICLE_TURRETDOWN);
+		CHECK_ACTION(VEHICLE_ENTER_EXIT);
+		CHECK_ACTION(CAMERA_CHANGE_VIEW_ALL_SITUATIONS);
+#ifndef BIND_VEHICLE_FIREWEAPON
+		CHECK_ACTION(PED_FIREWEAPON);
+#endif
+		CHECK_ACTION(GO_LEFT);
+		CHECK_ACTION(GO_RIGHT);
+		CHECK_ACTION(NETWORK_TALK);
+		CHECK_ACTION(SWITCH_DEBUG_CAM_ON);
+		CHECK_ACTION(TOGGLE_DPAD);
+		CHECK_ACTION(TAKE_SCREEN_SHOT);
+		CHECK_ACTION(SHOW_MOUSE_POINTER_TOGGLE);
+	}
+	return false;
+}
+
+#undef CHECK_ACTION
+#endif
+
 void CControllerConfigManager::DeleteMatchingActionInitiators(e_ControllerAction action, int32 key, eControllerType type)
 {
 	if (!GetIsKeyBlank(key, type))
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index 92017a93..d3c2293d 100644
--- a/src/core/ControllerConfig.h
+++ b/src/core/ControllerConfig.h
@@ -188,6 +188,10 @@ public:
 	void DeleteMatching1rstPersonControls       (e_ControllerAction action, int32 key, eControllerType type);
 	void DeleteMatchingActionInitiators         (e_ControllerAction action, int32 key, eControllerType type);
 
+#ifdef RADIO_SCROLL_TO_PREV_STATION
+	bool IsAnyVehicleActionAssignedToMouseKey(int32 key);
+#endif 
+
 	bool GetIsKeyBlank(int32 key, eControllerType type);
 	e_ControllerActionType GetActionType(e_ControllerAction action);
 
diff --git a/src/core/config.h b/src/core/config.h
index ad0df2da..54d53253 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -284,6 +284,7 @@ enum Config {
 // #define BETA_SLIDING_TEXT
 #define TRIANGULAR_BLIPS	// height indicating triangular radar blips, as in VC
 // #define XBOX_SUBTITLES	// the infamous outlines
+#define RADIO_OFF_TEXT
 #define PC_MENU
 
 #ifndef PC_MENU
@@ -348,6 +349,7 @@ enum Config {
 #define FREE_CAM		// Rotating cam
 
 // Audio
+#define RADIO_SCROLL_TO_PREV_STATION
 #ifndef AUDIO_OAL // is not working yet for openal
 #define AUDIO_CACHE // cache sound lengths to speed up the cold boot
 #endif